Current location issue in ArcGIS Maps in iOS - ios

I'm developing an application in which I have a map. I'm using ArcGIS SDK for showing map. Here I'm trying to show my current location when the map loads. I have passed my latitude and longitude to the x and y parameters of the ArcGIS function. This is the code for that function,
let lat = gpsLocation.location?.coordinate.latitude
let lng = gpsLocation.location?.coordinate.longitude
print(lat)
print(lng)
//zoom to custom view point
self.mapView.setViewpointCenter(AGSPoint(x: lat!, y: lng!, spatialReference: AGSSpatialReference.webMercator()), scale: 4e7, completion: nil)
self.mapView.interactionOptions.isMagnifierEnabled = true
But when I run the app it shows the wrong location in the map. It points to the wrong location. I have printed the lat and lng also. They are correct but the display of location is wrong in the map. How can I get the map to load my current location?
This is what it shows location when loads,

You're using latitude and longitude, i.e. a number of degrees (probably in WGS 1984), but then you're telling ArcGIS that they are in Web Mercator, i.e. a number of meters. That will definitely cause the behavior you see.
To fix it, simply replace webMercator() with WGS84().
Also, you are mixing up latitude and longitude. Latitude is y and longitude is x, and you have it the other way around.
In summary, replace your setViewpointCenter call with this:
self.mapView.setViewpointCenter(
AGSPoint(x: lon!, y: lat!, spatialReference: AGSSpatialReference.WGS84()),
scale: 4e7,
completion: nil
)

Related

Find coordinates in MKCoordinateRegion

I have a list of places with their coordinates (latitude + longitude).
I want to get only the places that are in the region displayed on the screen.
I can get the current region displayed on my screen with:
MKCoordinateRegion(center: CLLocationCoordinate2D, span: MKCoordinateSpan)
However I don't know under which parameters I should filter the coordinates of my list to only get the places in this region.
MKCoordinateSpan isn't convertible into a distance mesure from the center.
Thanks for helping
I think the simplest way is to get the displayed region as an MKMapRect with visibleMapRect and convert your coordinates to MKMapPoint using the MKMapPoint(_:) initializer. That way you can just call MKMapRect contains(_:).

How to check if a coordinate exists in GMSMutablePath before adding a coordinate

I'm trying to draw a polyline on the Google map as a object travels, sometimes the coordinates sent can get duplicated. I want to prevent duplicate coordinate from being added to the GMSMutablePath. Anyway this be achieved?
Currently I use the following method to add the coordinate to the GMSMutablePath. It adds duplicate values as well!
self.path.addLatitude(coordinate.latitude, longitude: coordinate.longitude)
After doing some digging in GoogleMaps SDK, I arrived at this solution. It may not be the perfect one but you can give it a try.
You can iterate through all the coordinates of the path by using coordinate(at:index) method of GMSMutablePath
Iterating the GMSMutablePath coordinates.
//Here path is your GMSMutablePath
for i in 0..<path.count() {
let coordinate = path.coordinate(at: i)
//The coordinate received is a CLLocationCoordinate2D type from which you can get the latitude and longitude.
//Here check the coordinate latitude and longitude is same as your received coordinate, make a return else add to your path.
//You can also keep a flag variable and at the end of all iterations, you can check whether the coordinate is present or not.
print(coordinate)
}

Google Maps iOS SDK Prevent camera zoom after each location update

I have an app which requires the user's location to be constantly updated so I can display their current coordinates and altitude. I'm doing this using the didUpdateLocations function:
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = locations.last {
mapView.camera = GMSCameraPosition(target: locationManager.location!.coordinate, zoom: 15, bearing: 0, viewingAngle: 0)
let locValue : CLLocationCoordinate2D = manager.location!.coordinate
let altitude : CLLocationDistance = Double(round(1000*manager.location!.altitude)/1000)
let long = Double(round(10000*locValue.longitude)/10000)
let lat = Double(round(10000*locValue.latitude)/10000)
let alt = String(altitude) + " m"
latitudeLabel.text = String(lat)
longitudeLabel.text = String(long)
altitudeLabel.text = alt
showLearningObjectsWithinRange(location)
}
}
The problem is, when I try to zoom in on a certain spot on the map, if I move the device even slightly the camera zooms back out again. Obviously this is because of the first line in my didUpdateLocations function setting the camera position, but if I remove that line, the map doesn't center to their location at all.
I tried moving the GMSCameraPosition code to the viewDidLoad, viewWillAppear, and several other places, but this caused the app to crash because it couldn't locate the user in time.
Does anyone have any suggestions on how to make this work? Thanks.
use this instead of that certain line (mapview.camera = ...)
mapView.animate(toLocation: CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude))
With regards to implementing location update, there was an issue posted in GitHub - Implement Responsive User Location Tracking Mode due to location update optimization and going through the thread, a given workaround to show the user location on the map is to call
nMapView.setMyLocationEnabled(true);
instead of:
nMapView.setMyLocationTrackingMode(MyLocationTrackingMode.TRACKING_FOLLOW);
Then, with regards to camera zoom, as discussed in Camera and View - Zoom, you can try setting a minimum or maximum zoom to restrict zoom level. As stated,
You can restrict the range of zoom available to the map by setting a min and max zoom level.
You may also try the solutions given in this SO post - Google Maps iOS SDK, Getting Current Location of user. Hope it helps.

How To Tell If User Is At A Specific Location?

Essentially what I need to do is find out if a user is at a specific place (IE at a venue). And if the user is, allow access to a specific ViewController.
I've been looking high and low for an answer to this problem online and surprisingly I haven't found anything. I will say I'm pretty new to iOS development.
I don't need anything as complex as geofencing like in the Ray Wenderlich tutorial, and I don't need to run it in the background. I also don't need to know if they entered or left. Just whether or not they are within that area or not when the user clicks a button.
I've gotten as far as being able to get the users location using CoreLocation, but I'm confused as to how I will go about identifying if the user is at the specific location. Ideally, I will want a radius of about 5 miles (It's a big location).
if you have the user's location as well as the venue's location you can do the following:
let radius: Double = 5 // miles
let userLocation = CLLocation(latitude: 51.499336, longitude: -0.187390)
let venueLocation = CLLocation(latitude: 51.500909, longitude: -0.177366)
let distanceInMeters = userLocation.distanceFromLocation(venueLocation)
let distanceInMiles = distanceInMeters * 0.00062137
if distanceInMiles < radius {
// user is near the venue
}
If you have the latitude and longitude of the venue, just create a CLLocation object for that and see how far the user is from that location.
// get the current user location, then...
let MinDistance = 100.0 // meters
let distance = venueLocation.distanceFromLocation(userLocation)
if distance < MinDistance {
// I'm close enough to the venue!
}

Assign a latitude/longitude point to a region

I have a map from jvectormap http://jvectormap.com/maps/countries/united-kingdom/ which displays country regions in SVG 'paths'.
I also have a set of objects with latitude and longitude co-ordinates.
Is it possible to assign each object to a particular region, given the co-ordinates and the SVG paths?
I found a way of doing it, but it's really hackish, and I'm sure there are better ways of doing it.
Anyhow, here's my solution to the problem:
jvm.Map.prototype.latLngToRegion = function (lat, lng) {
var pointOnMap = this.latLngToPoint(lat, lng),
pointOnPage = {
x: Math.round((pointOnMap.x + this.container.offset().left) - $(window).scrollLeft()),
y: Math.round((pointOnMap.y + this.container.offset().top) - $(window).scrollTop())
},
element = document.elementFromPoint(pointOnPage.x, pointOnPage.y),
region = $(element).attr('data-code');
return region; // note, this will only give you the region code, but from that you can read out most of what you need from jvectormaps itself.
}
Caveats are that the latitude and longitude you are looking for must be in view, for document.elementFromPoint to work. But you could maybe update the list on scroll and map pan etc.
Well, maybe you can take a look at how jvectormap matches your current mouse position to the region - you should be able to match your lat/lng coordinates in a similar way

Resources