I am trying to find out altitude from a given point, but I am not getting that with my iPad.
I have defined my altitude var like this:
var altitude: CLLocationDistance = 0.0
I have made this func:
func getAltitude(latitude: CLLocationDistance, longitude: CLLocationDistance) -> CLLocationDistance {
//Get altitude of touched point
locationManager.requestWhenInUseAuthorization()
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.desiredAccuracy = kCLLocationAccuracyBest
let touchPointLocation = CLLocation(latitude: latitude, longitude: longitude)
let altitude = touchPointLocation.altitude
return altitude
}
For example when I touch the map I tried to get altitude like this, inside the longpress:
let touchPoint = gestureRecognizer.location(in: self.map)
let coord = map.convert(touchPoint, toCoordinateFrom: self.map) //now this coord is working ok. Its touched point coordinates
let altitude = getAltitude(latitude: coord.latitude, longitude: coord.longitude)
print(altitude) //I get 0.0 here :(
Why is this wrong? How can I do this?
Related
I'm doing a very simple operation. I'm sorting through a bunch of locations in a map to create an enclosing circle, like so:
var maxLong: Double = -180
var maxLat: Double = -180
var minLong: Double = 180
var minLat: Double = 180
for coord in inCoordinates {
maxLong = max(coord.longitude, maxLong)
maxLat = max(coord.latitude, maxLat)
minLong = min(coord.longitude, minLong)
minLat = min(coord.latitude, minLat)
}
let nw: CLLocation = CLLocation(latitude: maxLat, longitude: minLong)
let se: CLLocation = CLLocation(latitude: minLat, longitude: maxLong)
let center = CLLocationCoordinate2D(latitude: (maxLat + minLat) / 2.0, longitude: (maxLong + minLong) / 2.0)
let radiusInMeters = abs(nw.distance(from: se)) / 2.0
return MKCircle(center: center, radius: radiusInMeters)
Pretty straightforward (Yeah, I know about the IDL issue, but I want to keep this simple).
What I'd like to know, is if there were some way I could boil the loop into a variant of reduce, where you would end up with something like this:
let enclosingRect: MKMapRect = inCoordinates.magikalReduce {
// Magic Happens Here -Queue Doug Henning GIF
}
So the returned rect contains the distilled points.
Yeah, I know that I can simply extend Array (with maybe a type qualifier) to do this with a calculated property, but that sort of defeats the purpose of this. The above is fairly efficient, and I'd rather not add overhead, just to be fancy (Which means, even if I could do it, it might be too inefficient to use).
This is more of a curiosity exploration than a technical need. The above code does fine for me, and is relatively zippy.
Do you mean
// calculate the enclosing rect with `reduce` and `union`, you have to create an `MKMapRect` from each coordinate
let enclosingRect = inCoordinates.reduce(MKMapRect.null) { $0.union(MKMapRect(origin: MKMapPoint($1), size: MKMapSize())) }
You can create a struct for holding the min/max longitude and latitude values, then use reduce, where you use the initial values for these for creating an initial result, then creating an updated version of the struct with the necessary min/max calculations.
struct MinMaxCoordinates {
let maxLong:Double
let maxLat:Double
let minLong:Double
let minLat:Double
}
let minMaxCoordinates = inCoordinates.reduce(MinMaxCoordinates(maxLong: -180, maxLat: -180, minLong: 180, minLat: 180), {minMax, coord in
return MinMaxCoordinates(maxLong: max(minMax.maxLong, coord.longitude), maxLat: max(minMax.maxLat, coord.latitude), minLong: min(minMax.minLong, coord.longitude), minLat: max(minMax.minLat, coord.latitude))
})
let nw: CLLocation = CLLocation(latitude: minMaxCoordinates.maxLat, longitude: minMaxCoordinates.minLong)
let se: CLLocation = CLLocation(latitude: minMaxCoordinates.minLat, longitude: minMaxCoordinates.maxLong)
let center = CLLocationCoordinate2D(latitude: (minMaxCoordinates.maxLat + minMaxCoordinates.minLat) / 2.0, longitude: (minMaxCoordinates.maxLong + minMaxCoordinates.minLong) / 2.0)
let radiusInMeters = abs(nw.distance(from: se)) / 2.0
return MKCircle(center: center, radius: radiusInMeters)
How can do dynamic google marker after get the coordinates from server i am fetching latitude and longitude from REST API
my showMarker function is given below:
private func showMarker(_ lat: String, _ lng: String, _ description: String){
let latitude: CLLocationDegrees = Double(lat) ?? 0.00
let longitude: CLLocationDegrees = Double(lng) ?? 0.00
print("Latitude: \(latitude), Longitude: \(longitude)")
let position = CLLocationCoordinate2DMake(latitude, longitude)
let marker = GMSMarker(position: position)
marker.title = ""
marker.map = self.mapView
}
If the below code run in ViewDidLoad() that's working fine
self.camera = GMSCameraPosition.camera(withLatitude: 6.244880, longitude: 7.001920, zoom: 10.0)
mapView.camera = self.camera
mapView.animate(toZoom: 10.0)
self.mapView = GMSMapView.map(withFrame: self.view.bounds, camera: self.camera)
But when i called them after the above code after the showMarker function then camera object get nil
I just want to add the marker after fetching the data through rest api
i have info window that shows after tapped, but how to make it always appear? Without user tap on the marker. I'm using Google Maps.
here's my code :
mapView.delegate = self
let camera = GMSCameraPosition.camera(withLatitude: coordinate.lat, longitude: coordinate.long, zoom: 20)
mapView.animate(to: camera)
for state in states {
let marker = GMSMarker()
marker.position = CLLocationCoordinate2DMake(state.lat, state.long)
print(marker.position)
marker.title = "Country"
marker.snippet = "Places"
marker.map = mapView
mapView.selectedMarker = marker
marker.map = mapView
}
thanks before
First we need to Add a marker.
let position = CLLocationCoordinate2D(latitude: 10, longitude: 10)
let marker = GMSMarker(position: position)
marker.title = "Hello World"
marker.map = mapView
We can Customize the marker image by this:-
let position = CLLocationCoordinate2D(latitude: 51.5, longitude: -0.127)
let london = GMSMarker(position: position)
london.title = "London"
london.icon = UIImage(named: "house")
london.map = mapView
//To change the Marker Opacity use below
marker.opacity = 0.6
To Rotate a marker:-
let position = CLLocationCoordinate2D(latitude: 51.5, longitude: -0.127)
let degrees = 90.0
let london = GMSMarker(position: position)
london.groundAnchor = CGPoint(x: 0.5, y: 0.5)
london.rotation = degrees
london.map = mapView
And to Add an info window:-
let position = CLLocationCoordinate2D(latitude: 51.5, longitude: -0.127)
let london = GMSMarker(position: position)
london.title = "London"
london.snippet = "Population: 8,174,100"
london.map = mapView
To Set an info window to refresh automatically
marker.tracksInfoWindowChanges = true
To Change the position of an info window
let position = CLLocationCoordinate2D(latitude: 51.5, longitude: -0.127)
let london = GMSMarker(position: position)
london.title = "London"
london.snippet = "Population: 8,174,100"
london.infoWindowAnchor = CGPoint(x: 0.5, y: 0.5)
london.icon = UIImage(named: "house")
london.map = mapView
For more details you can go Here
try to move mapView.selectedMarker = marker to delegate function mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool function
I have created code that produces a geotargeting area represented by an annotation and MKCircle. The app notifies the user when they have entered and exited a region. Everything is working fine but I cannot figure out how to get the app to hold/display multiple regions (only one annotation/circle will show) here are a few snippets of my code:
override func viewDidLoad() {
super.viewDidLoad( )
//setup locationManager
locationManager.delegate = self
locationManager.distanceFilter = kCLLocationAccuracyNearestTenMeters
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
//setup mapView
mapView.delegate = self
mapView.showsUserLocation = true
mapView.userTrackingMode = .Follow
//setup test data will need to link coredata to pass in (LocationLabel, radius, address)
setupData("Test1", radius: 100, Address: "735 Main Rd, Clemson")
setupData("Test2", radius: 100, Address: "821 Main Rd, Clemson")
setupData("Test3", radius: 100, Address: "720 Main Rd, Clemson")
}
func setupData( Label: String, radius: Double, Address: String ) {
// check if system can monitor regions
if CLLocationManager.isMonitoringAvailableForClass(CLCircularRegion.self) {
//region data need to put in its own class to read multiple regions
let title = Label
let regionRadius = radius // in meters
let address = Address // street, city, state zip
//takes in the address of a location and converts it into 2d coordinates (lat/long)
let geocoder = CLGeocoder()
geocoder.geocodeAddressString(address) { (placemarks, error) in
if let placemarks = placemarks {
if placemarks.count != 0 {
let coordinates = placemarks.first!.location
let coordinate = coordinates?.coordinate
//setup region this will read an object with a saved coordinate and name
var region = CLCircularRegion(center: CLLocationCoordinate2D(latitude: coordinate!.latitude,
longitude: coordinate!.longitude), radius: regionRadius, identifier: title)
self.locationManager.startMonitoringForRegion(region)
//setup annotation
let annotation = MKPointAnnotation()
annotation.coordinate = coordinate!;
annotation.title = "\(title)";
self.mapView.addAnnotation(annotation)
//setup circle
let circle = MKCircle(centerCoordinate: coordinate!, radius: regionRadius)
self.mapView.addOverlay(circle)
}
else {
print("System can't track regions")
}
}
}
}
}
You have to implement the renderForOverlay function of MKMapViewDelegate to actually see those overlays that you have added. Try to increase your radius as well if you want it to see right away without zooming in.
func mapView(mapView: MKMapView, rendererForOverlay overlay: MKOverlay) -> MKOverlayRenderer
{
if let overlay = overlay as? MKCircle
{
let circleRenderer = MKCircleRenderer(circle: overlay)
circleRenderer.fillColor = UIColor.blueColor()
return circleRenderer
}
return MKOverlayRenderer(overlay: overlay)
}
I'm trying to create a region similar to a circle radius using CLLocation. I understand radius logic and how its measured in meters, but not so clear on a MKCoordinate region and how long delta and lat delta translate to area. I would like to get a 75 mile region. Here is my code....
let center = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
If you could please provide an explanation more than just a short answer it would be appreciated.
If you're trying to create an actual circular region:
let center = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
let radius: CLLocationDistance = 60350.4 // meters for 37.5 miles
let regionIdentifier = "CircularRegion" // any desired String
let circularRegion = CLCircularRegion(center: center, radius: radius, identifier: regionIdentifier)
You could use MKCoordinateRegionMakeWithDistance function:
Creates a new MKCoordinateRegion from the specified coordinate and
distance values.
func MKCoordinateRegionMakeWithDistance(
_ centerCoordinate: CLLocationCoordinate2D,
_ latitudinalMeters: CLLocationDistance,
_ longitudinalMeters: CLLocationDistance) -> MKCoordinateRegion
centerCoordinate - The center point of the new coordinate region.
latitudinalMeters - The amount of north-to-south distance (measured in meters) to use for the span.
longitudinalMeters - The amount of east-to-west distance (measured in meters) to use for the span.
So you will have something like:
let rect = MKCoordinateRegionMakeWithDistance(center, 50 * 1609.34, 50 * 1609.34)