I am a newbie in Swift. I was ale to get 2 markers on Google Maps:
import UIKit
import GoogleMaps
class ViewController: UIViewController {
// You don't need to modify the default init(nibName:bundle:) method.
override func loadView() {
let camera = GMSCameraPosition.cameraWithLatitude(37.0902, longitude: -95.7129, zoom: 3.0)
let mapView = GMSMapView.mapWithFrame(CGRect.zero, camera: camera)
mapView.myLocationEnabled = true
view = mapView
let state_marker = GMSMarker()
state_marker.position = CLLocationCoordinate2D(latitude: 61.370716, longitude: -152.404419)
state_marker.title = "Alaska"
state_marker.snippet = "Hey, this is Alaska"
state_marker.map = mapView
let state_marker1 = GMSMarker()
state_marker1.position = CLLocationCoordinate2D(latitude: 32.806671, longitude: -86.791130)
state_marker1.title = "Alabama"
state_marker1.snippet = "Hey, this is Alabama"
state_marker1.map = mapView
}
}
I need to add 51 more markers to different latitude and longitude for each state with different title and snippet.
I can probably just copy this block 51 times but is there a way to optimize this code?
You should create a struct like this:
struct State {
let name: String
let long: CLLocationDegrees
let lat: CLLocationDegrees
}
Then create an array of this struct in your VC:
let states = [
State(name: "Alaska", long: -152.404419, lat: 61.370716),
State(name: "Alabama", long: -86.791130, lat: 32.806671),
// the other 51 states here...
]
Now you can just loop through the array, adding markers in each iteration:
for state in states {
let state_marker = GMSMarker()
state_marker.position = CLLocationCoordinate2D(latitude: state.lat, longitude: state.long)
state_marker.title = state.name
state_marker.snippet = "Hey, this is \(state.name)"
state_marker.map = mapView
}
You might also want to add a dictionary that stores the names of the states as keys and the corresponding GMSMarker as value. This way, you can modify the markers later.
var markerDict: [String: GMSMarker] = [:]
override func loadView() {
for state in states {
let state_marker = GMSMarker()
state_marker.position = CLLocationCoordinate2D(latitude: state.lat, longitude: state.long)
state_marker.title = state.name
state_marker.snippet = "Hey, this is \(state.name)"
state_marker.map = mapView
markerDict[state.name] = state_marker
}
}
Related
I'm developing an app that have a multiple location/marker.
I created a struct
let states = [
State(name: "Zoo 1", long: 2.276537, lat: 102.2989),
State(name: "Zoo 2", long: 2.2772141, lat: 102.2984333),
// the other 51 states here...
]
and try a looping but the marker did not display
for state in states {
let state_marker = GMSMarker()
state_marker.position = CLLocationCoordinate2D(latitude: state.lat, longitude: state.long)
state_marker.title = state.name
state_marker.snippet = "Hey, this is \(state.name)"
state_marker.map = mapView
}
when i do like below, it is working. but i know it's not a better way
let state_marker = GMSMarker()
state_marker.position = CLLocationCoordinate2D(latitude: 2.276622, longitude: 102.2989)
state_marker.title = "Zoo 1"
state_marker.snippet = "Hey, this is Zoo 1"
state_marker.map = mapView
let state_marker1 = GMSMarker()
state_marker1.position = CLLocationCoordinate2D(latitude: 2.2772141, longitude: 102.2984333)
state_marker1.title = "Zoo 2"
state_marker1.snippet = "Hey, this is Zoo 2"
state_marker1.map = mapView
Does anyone know what is wrong in my code?
You swapped the lat and Lon in first try , it works in second as longitude is 102.2989 , but in first you swapped them
for state in states {
let state_marker = GMSMarker()
state_marker.position = CLLocationCoordinate2D(latitude: state.lat, longitude: state.long)
state_marker.title = state.name
state_marker.snippet = "Hey, this is \(state.name)"
state_marker.map = mapView
}
So change array to this
let states = [
State(name: "Zoo 1", long:102.2989 , lat: 2.276537),
State(name: "Zoo 2", long:102.2984333 , lat: 2.2772141),
// the other 51 states here...
]
Edit :
Latitude measurements range from 0° to (+/–)90°. Longitude measures how far east or west of the prime meridian a place is located. The prime meridian runs through Greenwich, England. Longitude measurements range from 0° to (+/–)180°
I am building an ios application that uses a google map to display the location of the places return in the server. I manage to display the result in the initial load of the map, but when I want to search new plaaces and reload the markers in the map. Unfortunately the app was crashes.
Hope for your help.
Thank you.
Here is my code in the ViewController to initially display the markers:
func setUpMap() {
let camera = GMSCameraPosition.camera(withLatitude: -33.86, longitude: 151.20, zoom: 10.0)
self.mapView.camera = camera
let map_view = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
for data in arrData {
let long = data["LONGITUDE"].string!
let lat = data["LATITUDE"].string!
if long != "" || lat != "" {
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: CLLocationDegrees(lat)!, longitude: CLLocationDegrees(long)!)
marker.title = ""
marker.snippet = "Hey, this is sample"
marker.icon = UIImage(named: "locator")
marker.map = self.mapView
bounds = bounds.includingCoordinate(marker.position)
}
}
// fit to bounds
mapView.animate(with: GMSCameraUpdate.fit(bounds, withPadding: 50.0))
self.mapView = map_view
}
Here is my code to reload/reset the markers in the map.
func reloadMarkers() {
self.mapView.clear()
let camera = GMSCameraPosition.camera(withLatitude: -33.86, longitude: 151.20, zoom: 10.0)
self.mapView.camera = camera
let map_view = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
var _bounds = GMSCoordinateBounds()
for data in arrData {
let long = data["LONGITUDE"].string!
let lat = data["LATITUDE"].string!
if long != "" || lat != "" {
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: CLLocationDegrees(lat)!, longitude: CLLocationDegrees(long)!)
marker.title = ""
marker.snippet = "Hey, this is sample"
marker.icon = UIImage(named: "locator")
marker.map = self.mapView
_bounds = _bounds.includingCoordinate(marker.position)
}
}
// fit to bounds
mapView.animate(with: GMSCameraUpdate.fit(bounds, withPadding: 50.0))
self.mapView = map_view
}
Thanks for the help.
Cheers!
I found a solution, please see sample code below.
func reloadMarkers() {
let camera = GMSCameraPosition.camera(withLatitude: 12.0377995, longitude: 122.6408281, zoom: 10.0)
let map_view = GMSMapView.map(withFrame: self.brachMapView.bounds, camera: camera)
map_view.camera = camera
var bounds = GMSCoordinateBounds()
for data in arrData {
let long = data["LONGITUDE"].string!
let lat = data["LATITUDE"].string!
if long != "" || lat != "" {
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: CLLocationDegrees(lat)!, longitude: CLLocationDegrees(long)!)
marker.title = ""
marker.snippet = "Hey, this is sample"
marker.icon = UIImage(named: "locator")
marker.map = map_view
bounds = bounds.includingCoordinate(marker.position)
}
}
// fit to bounds
map_view.animate(with: GMSCameraUpdate.fit(bounds, withPadding: 50.0))
self.brachMapView.addSubview(map_view)
}
Thanks.
Cheers
I have to plot multiple pins in a Google Map view, and then zoom to the user's current location. Pins are plotted successfully but not zoomed to current location. Any help would be appreciated
override func viewDidAppear(_ animated: Bool) {
if (self.googleMapsView == nil) {
self.googleMapsView = GMSMapView(frame: self.mapViewContainer.frame)
self.view.addSubview(self.googleMapsView)
print(AppDelegate.getAppDelegate().mapArray)
googleMapsView.clear()
for i in 0...AppDelegate.getAppDelegate().mapArray.count - 1 {
let lon = Double ((AppDelegate.getAppDelegate().mapArray[i]["lon"] as? String)!)
let lat = Double ((AppDelegate.getAppDelegate().mapArray[i]["lat"] as? String)!)
let tit = AppDelegate.getAppDelegate().mapArray[i]["location"] as? String
locateWithLongitude(lon: lon!,andLatitude: lat! ,andTitle: tit!)
}
let marker = GMSMarker(position: AppDelegate.getAppDelegate().myLocation)
let camera = GMSCameraPosition.camera(withLatitude: AppDelegate.getAppDelegate().myLocation.latitude, longitude: AppDelegate.getAppDelegate().myLocation.longitude, zoom: 11)
self.googleMapsView.camera = camera
marker.title = AppDelegate.getAppDelegate().sublocality
marker.map = self.googleMapsView
self.googleMapsView.animate(to: camera)
}
}
func locateWithLongitude(lon: Double, andLatitude lat: Double, andTitle title: String) {
DispatchQueue.main.async() { () -> Void in
let position = CLLocationCoordinate2DMake(lat, lon)
let marker = GMSMarker(position: position)
let camera = GMSCameraPosition.camera(withLatitude: lat, longitude: lon, zoom: 0)
self.googleMapsView.camera = camera
marker.title = title
marker.map = self.googleMapsView
}
}
Your zoom is set to 0, increase it to 15/16 like bellow.
let camera = GMSCameraPosition.camera(withLatitude: lat, longitude: lon, zoom: 16)
I have been trying to add multiple markers to google map using for loop but it does not add to the google map. Adding one marker works or if writing code for each marker without for loop.
Declaration
#IBOutlet weak var googleMapView: GMSMapView! // set in story board
var shopsLatLong = [Double: Double]() // shops dictionary for lat long
For loop not working:
for (key,value) in shopsLatLong{
//Setting camera
self.googleMapView.camera = GMSCameraPosition.camera(withLatitude: key, longitude: value, zoom: 6.0)
let marker = GMSMarker()
marker.position = CLLocationCoordinate2DMake(key, value)
marker.title = "Store Name"
marker.snippet = "Pakistan"
marker.map = self.googleMapView
print("Marker is \(marker)")
}
How to get this working? Kindly help me in figuring out this issue
Don't make class variable for marker. You have to create a local variable for the marker.
If you create a class variable then you will get only one marker. Because you are overriding the values inside the for loop
for (key,value) in shopsLatLong{
//Get the latitude and longitude of the marker and pass it here.
let lat = //latitude for marker
let lon = //longitude for marker
var marker = GMSMarker()
marker.position = CLLocationCoordinate2DMake(lat, lon)
marker.title = "Store Name"
marker.snippet = "Pakistan"
marker.map = self.googleMapView
}
First Create a array like
func setData(){
//create dictionary and store in mai array
var dicMapData : NSMutableDictionary = NSMutableDictionary()
dicMapData["title"] = "Kalasagar Shopping Hub"
dicMapData["image"] = "background9"
dicMapData["subtitle"] = "ShoppingHub"
dicMapData["latitude"] = 23.0669 // store latitude for specigic location
dicMapData["longitude"] = 72.5328 // store longitude for specigic location
arrMultipleAnotation.add(dicMapData)
dicMapData = NSMutableDictionary()
dicMapData["title"] = "Satadhar Cross Road"
dicMapData["image"] = "background8"
dicMapData["subtitle"] = "Crossroad"
dicMapData["latitude"] = 23.0629
dicMapData["longitude"] = 72.5328
arrMultipleAnotation.add(dicMapData)
dicMapData = NSMutableDictionary()
dicMapData["title"] = "Sola Bridge"
dicMapData["image"] = "menu-icon"
dicMapData["subtitle"] = "Bridge"
dicMapData["latitude"] = 23.0695
dicMapData["longitude"] = 72.5232
arrMultipleAnotation.add(dicMapData)
let initialLocation = CLLocation(latitude: 23.0669, longitude: 72.5289)
centerMapOnLocation(location: initialLocation)
//For Displayig Multiple Pin in mapview using array and loop
for locations in arrMultipleAnotation{
//Setting camera
self.googleMapView.camera = GMSCameraPosition.camera(withLatitude: dicCurrent["latitude"] as! Double, longitude: dicCurrent["longitude"] as! Double, zoom: 6.0)
self.marker = GMSMarker()
self.marker.position = CLLocationCoordinate2D(latitude: dicCurrent["latitude"] as! Double, longitude: dicCurrent["longitude"] as! Double)
self.marker.title = dicCurrent["title"] as? String
self.marker.snippet = dicCurrent["subtitle"] as? String
self.marker.map = self.googleMapView
print("Marker is \(self.marker)")
}
I hope It's work for you
I also had a similar issue and I was able to figure it out. Actually I wasn't overriding prepare for segue and the button was also directly linked to the storyboard due to which my view presented it self first before I even got the data. So here is what I did maybe it works for you too.
Override prepare for segue and set the variables there
Remove the segue link (if any) which is linking directly with the button
Add new segue from the top of the view controller to the new segue.
Build and Run.
I hope it resolves the issue for you too.
Change This code..
#IBOutlet weak var googleMapView: GMSMapView! // set in story board
var shopsLatLong = [Double: Double]() // shops dictionary for lat long
for (key,value) in shopsLatLong{
//Setting camera
self.googleMapView.camera = GMSCameraPosition.camera(withLatitude: key, longitude: value, zoom: 6.0)
let marker = GMSMarker()
marker.position = CLLocationCoordinate2DMake(key, value)
marker.title = "Store Name"
marker.icon = image
marker.snippet = "Pakistan"
marker.map = self.googleMapView
print("Marker is \(self.marker)")
}
You should use a markers property, which is an array, and add your markers to this array. That way there will be a strong reference to all of your marker objects and you can easily work with them.
Also, a dictionary isn't really a good data structure for this purpose. I would suggest an array of struct where the struct has a latitude and longitude or even an array of tuples of (Double,Double)
#IBOutlet weak var googleMapView: GMSMapView! // set in story board
var shopsLatLong = [(Double,Double)]() // shops dictionary for lat long
var markers = [GMSMarker]()
for (position) in shopsLatLong{
//Setting camera
self.googleMapView.camera = GMSCameraPosition.camera(withLatitude: position.0, longitude: position.1, zoom: 6.0)
let marker = GMSMarker()
marker.position = CLLocationCoordinate2DMake(position.0, position.1)
marker.title = "Store Name"
marker.snippet = "Pakistan"
marker.map = self.googleMapView
self.markers.append(marker)
print("Marker is \(marker)")
}
How can I show these kind of car images in picture on google maps
according to latitude & longitude?
I tried the following code, but I got the following incorrect result
let marker1 = GMSMarker()
let marker2 = GMSMarker()
let marker3 = GMSMarker()
let marker4 = GMSMarker()
let marker5 = GMSMarker()
let markerImage = UIImage(named: "white_car_icon copy.png")!.withRenderingMode(.alwaysTemplate)
let markerView = UIImageView(image: markerImage)
marker1.position = CLLocationCoordinate2D(latitude: 12.9077923, longitude: 77.586962)
marker2.position = CLLocationCoordinate2D(latitude: 12.9077923, longitude: 77.586962)
marker3.position = CLLocationCoordinate2D(latitude: 12.9077856, longitude: 77.58695950000001)
marker4.position = CLLocationCoordinate2D(latitude: 12.90782858, longitude: 77.58678956)
marker5.position = CLLocationCoordinate2D(latitude: 12.90780888511306, longitude: 77.58487723767757)
marker1.iconView = markerView
marker1.map = mapView
marker2.iconView = markerView
marker2.map = mapView
marker3.iconView = markerView
marker3.map = mapView
marker4.iconView = markerView
marker4.map = mapView
marker5.iconView = markerView
marker5.map = mapView
If anyone could help me with this, I'd be thankful to you. I have been trying it for the past 4 days, but didn't get correct output.
The right option is using the icon property
marker5.icon = UIImage(named: "paradero")
With this you can set any image you want.