I have the following code:
func mapView(mapView: GMSMapView, didTap marker: GMSMarker){
let lat: CLLocationDegrees = marker.position.latitude
let lng: CLLocationDegrees = marker.position.longitude
var formattedCoordinate = CLLocationCoordinate2D(latitude: lat,longitude: lng)
markersArray.remove(formattedCoordinate)
self.clean()
}
func mapView(mapView: GMSMapView, didBeginDragging marker: GMSMarker){
let lat: CLLocationDegrees = marker.position.latitude
let lng: CLLocationDegrees = marker.position.longitude
var formattedCoordinate = CLLocationCoordinate2D(latitude: lat,longitude: lng)
markersArray.remove(formattedCoordinate)
}
As you can see I am trying to "remove" the "formattedCoordinate" from markersArray. I saw that there are options like .filter and other methods which enables removing an element at a specific index, but here I would like to remove that specific coordinate from the array. How do I do that?
markers = markers.filter({ (coordinateToRemove) -> Bool in
return coordinateToRemove.latitude == formattedCoordinate.latitude && coordinateToRemove.longitude == formattedCoordinate.longitude
})
I had the same problem solved it by rounding off the values of latitude and longitude(as they can be different by some decimal in formattedCoordinate Object) that you are comparing using
round(coordinateToRemove.latitude)
and comparing them separately.
Related
I have a method I want to call however when I get back the center of the map, it is in CLLocationCoordinate2D type.
How do I put the results of CLLocationCoordinate2D into CLLocation?
Figured it out.
When mapView changes region, get the Lat and Lon from CLLocationCoordinate2D and create a CLLocation variable with the lat and lon passed in.
func mapView(mapView: MKMapView!, regionDidChangeAnimated animated: Bool){
var centre = mapView.centerCoordinate as CLLocationCoordinate2D
var getLat: CLLocationDegrees = centre.latitude
var getLon: CLLocationDegrees = centre.longitude
var getMovedMapCenter: CLLocation = CLLocation(latitude: getLat, longitude: getLon)
self.lastLocation = getMovedMapCenter
self.fetchCafesAroundLocation(getMovedMapCenter)
}
How can i sort the array based on distance from current location and show in tableview .when i use sorting am not getting any proper results ,am getting the array with random distance.can any one guide me for solve this issue
To sort locations based on distance from current location in best possible way would be have location points in form of struct
struct LocationPoints {
var latitude: CLLocationDegrees
var longitude: CLLocationDegrees
func distance(to currentLocation: CLLocation) -> CLLocationDistance {
return CLLocation(latitude: self.latitude, longitude: self.longitude).distance(from: currentLocation)
}
}
Let suppose you have an array of LocationPoints having latitude & longitude
var coordinates: [LocationPoints] = []
coordinates.append(LocationPoints(latitude: Double(25), longitude: Double(24)))
coordinates.append( LocationPoints(latitude: Double(23), longitude: Double(22)))
sort function
coordinates = sortLocationsWithCurrentLocation(locations: coordinates, currentLocation: CLLocation(latitude: Double(20), longitude: Double(21)))
func sortLocationsWithCurrentLocation(locations:[LocationPoints],currentLocation:CLLocation) -> [LocationPoints] {
//set here current position as current location
let currentPosition : CLLocation = CLLocation(latitude: 30, longitude: 24)
let sortedLocations = locations.sorted(by: { (point1 : LocationPoints, point2 :LocationPoints) -> Bool in
if point1.distance(to: currentPosition) < point2.distance(to: currentPosition)
{
return true
}
return false
})
return sortedLocations
}
I want to show full screen mapView, always get Latitude and longitude of center of mapView and show marker in this point.
func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition) {
let lat = mapView.camera.target.latitude
print(lat)
let lon = mapView.camera.target.longitude
print(lon)
marker.position = CLLocationCoordinate2DMake(CLLocationDegrees(centerPoint.x) , CLLocationDegrees(centerPoint.y))
marker.map = self.mapView
returnPostionOfMapView(mapView: mapView)
}
func mapView(_ mapView: GMSMapView, idleAt position: GMSCameraPosition) {
print("idleAt")
//called when the map is idle
returnPostionOfMapView(mapView: mapView)
}
func returnPostionOfMapView(mapView:GMSMapView){
let geocoder = GMSGeocoder()
let latitute = mapView.camera.target.latitude
let longitude = mapView.camera.target.longitude
let position = CLLocationCoordinate2DMake(latitute, longitude)
geocoder.reverseGeocodeCoordinate(position) { response , error in
if error != nil {
print("GMSReverseGeocode Error: \(String(describing: error?.localizedDescription))")
}else {
let result = response?.results()?.first
let address = result?.lines?.reduce("") { $0 == "" ? $1 : $0 + ", " + $1 }
print(address)
// self.searchBar.text = address
}
}
}
i use this code in how can know Latitude and longitude that return in returnPostionOfMapView method is position of center mapView and show marker in this position?
You are doing it right to get the center of the map by using the google maps's func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition) delegate.
Take a variable for center coordinates
var centerMapCoordinate:CLLocationCoordinate2D!
Implement this delegate to know the center position.
func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition) {
let latitude = mapView.camera.target.latitude
let longitude = mapView.camera.target.longitude
centerMapCoordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
self.placeMarkerOnCenter(centerMapCoordinate:centerMapCoordinate)
}
Function to place a marker on center point
func placeMarkerOnCenter(centerMapCoordinate:CLLocationCoordinate2D) {
let marker = GMSMarker()
marker.position = centerMapCoordinate
marker.map = self.mapView
}
In this case you will get a lot of markers. So keep a global hold of marker and check if it is already present, just change the position
var marker:GMSMarker!
func placeMarkerOnCenter(centerMapCoordinate:CLLocationCoordinate2D) {
if marker == nil {
marker = GMSMarker()
}
marker.position = centerMapCoordinate
marker.map = self.mapView
}
I'm trying to figure out if there is any shorter syntax in Swift for the last line here:
var startPosition: CLLocationCoordinate2D?
var latitude: Double?
var longitude: Double?
// ...
// Here I have skipped some code which may or may not assign values
// to "latitude" and "longitude".
// ...
if latitude != nil && longitude != nil {
startPosition = CLLocationCoordinate2DMake(latitude!, longitude!)
}
As you can see, I want to set the "startPosition" based on "latitude" and "longitude", if those values have been assigned. Otherwise, I accept that the "startPosition" will not be initialized.
I guess this must be possible with "if let" or something similar, but I have failed to figure out how. (I'm experienced in Objective-C, but have just started to learn Swift.)
This is not shorter, but you can simply do
if let latitude = latitude, let longitude = longitude {
startPosition = CLLocationCoordinate2D(latitude: latitude,
longitude: longitude)
}
Notice I used just CLLocationCoordinate2D, not CLLocationCoordinate2DMake. Swift provides constructors without the "make" to most common objects, so you shouldn't usually have to use "make" in constructors.
If you don't want to execute any code after if they are nil use a guard.
var startPosition: CLLocationCoordinate2D?
var latitude: Double?
var longitude: Double?
guard let latitude = latitude && longitude = longitude else {
return
}
startPosition = CLLocationCoordinate2DMake(latitude, longitude)
Clear way
if let latitude = latitude, longitude = longitude {
startPosition = CLLocationCoordinate2D(latitude: latitude,
longitude: longitude)
}
CLLocationCoordinate2D is a struct, it's better if you use the struct initializer. Notice there is only one "let" needed in the if statement.
If i understood the question correctly, you could say
var startPosition: CLLocationCoordinate2D?
var latitude: Double?
var longitude: Double?
if latitude != nil && longitude != nil {
startPosition = CLLocationCoordinate2DMake(latitude!, longitude!)
} else {
startPosition = nil
}
I have a method I want to call however when I get back the center of the map, it is in CLLocationCoordinate2D type.
How do I put the results of CLLocationCoordinate2D into CLLocation?
Figured it out.
When mapView changes region, get the Lat and Lon from CLLocationCoordinate2D and create a CLLocation variable with the lat and lon passed in.
func mapView(mapView: MKMapView!, regionDidChangeAnimated animated: Bool){
var centre = mapView.centerCoordinate as CLLocationCoordinate2D
var getLat: CLLocationDegrees = centre.latitude
var getLon: CLLocationDegrees = centre.longitude
var getMovedMapCenter: CLLocation = CLLocation(latitude: getLat, longitude: getLon)
self.lastLocation = getMovedMapCenter
self.fetchCafesAroundLocation(getMovedMapCenter)
}