I am new to iOS development. This is regarding Marker info window in Google Maps iOS SDK.
I understand, we can create a marker with info window using GMSMarkerOption.
GMSMarkerOption *myLocationOption = [GMSMarkerOption alloc];
myLocationOption .title = #"My Location";
myLocationOption .snippet = #"Lat:...., Lang:....";
[mapView addMarkerOption:myLocationOption];
As per the above code, Marker displayed in the Map View as expected.
And tapping on marker shows the "My Location" info window in Google maps which is good.
Is there anyway we can show the info window programmatically when the user goes to Custom Map Screen?
This has changed on Google Maps SDK and it's easier to understand:
GMSMarker *marker = [[GMSMarker alloc] init];
marker.position = coordinate;
marker.title = #"Location selected";
marker.snippet = #"Testing";
marker.map = mapView_;
//Show info window on map
[mapView_ setSelectedMarker:marker];
You use now setSelectedMarker method to show an info window of a marker
GMSMarkerOptions *myLocationOptions = [GMSMarkerOptions options];
myLocationOptions.title = #"My Location";
myLocationOptions.snippet = #"Lat:...., Lang:....";
mapView.selectedMarker = [mapView addMarkerWithOptions:myLocationOptions];
(note that it's Options, not Option)
Swift 3.0
func addMarker(_ location:CLLocation){
var locationMarker: GMSMarker!
if locationMarker != nil {
locationMarker.map = nil
}
locationMarker = GMSMarker(position: location.coordinate)
locationMarker.map = mapView
locationMarker.appearAnimation = kGMSMarkerAnimationPop
locationMarker.icon = GMSMarker.markerImage(with: UIColor.green)
locationMarker.opacity = 0.85
locationMarker.isFlat = true
locationMarker.snippet = "My Location"
mapView.selectedMarker=locationMarker
}
below line is the answer
mapView.selectedMarker=locationMarker
swift 3
self.mapView.selectedMarker = marker
In the case of swift 3, you can open the snipet usint the selectedMarker
If you are creating the marker in a similar way to:
marker.position = CLLocationCoordinate2D(latitude: 34.1331168, longitude: -118.3550723)
marker.title = "My super place name"
marker.snippet = "Are you looking a place to play? This is your place! "
marker.appearAnimation = kGMSMarkerAnimationPop
marker.map = self.mapView
// Below line will shows the infowindow for marker with out tapping on it
[mapView setSelectedMarker:myLocationOptions]; // myLocationOptions is your desired GMSMarker to show Infowindow with out tapping .
Happy Coding :)
mMapView.selectedMarker = marker
GMSMarkerOptions is deprecated. Using this helped me to show info window without tapping-
func mapView(_ mapView: GMSMapView, idleAt position: GMSCameraPosition) {
myMapView.selectedMarker = myGMSMarker
}
--> It shows multiple infoWindows without tapping on marker. You can easily customise it.
for i in 0..
let dict = arrNearByPlacesArray.object(at: i) as? NSDictionary ?? [:]
let lat = dict.object(forKey: "latitude") as? String ?? ""
let long = dict.object(forKey: "longitude") as? String ?? ""
let company_id = dict.object(forKey: "company_id") as? String ?? ""
let totaljobs = dict.object(forKey: "totaljobs") as? String ?? ""
let location = CLLocationCoordinate2D(latitude: Double(lat) ?? 0.0, longitude: Double(long) ?? 0.0)
print("location: \(location)")
let marker = GMSMarker()
//marker.icon = UIImage(named: "maps")
let viewData = Bundle.main.loadNibNamed("MarkerXibView", owner: self, options: nil)?.first as! MarkerXibView . //UIView
marker.iconView = viewData . //UIView
marker.position = location
marker.accessibilityLabel = company_id
marker.map = vwGoogleMap
}
Related
i am trying to create clusters in my google map. When i show clusters on map i want to show only the cluster count and when the cluster is clicked or zoom then only i want to show my Custom marker view.
Bu the marker view are already present before clustering and when i zoom in a cluster, the default pins are shown, which i dont want.
below is the code for clustering
for data in self.map_data {
//check if map data is on or off and show map data accordignly
let offerdata = data
let geocoder = CLGeocoder()
let strAddress = "\(offerdata.agent_street ?? "")"+" "+"\(offerdata.agent_city ?? "")"+" "+"\(offerdata.agent_zipcode ?? "")"
//MARK: GEOCODER FOR GETTING LAT LONG BASE ON ADDRESS
geocoder.geocodeAddressString(strAddress) {
placemarks, error in
let placemark = placemarks?.first
let lat = Double(placemark?.location?.coordinate.latitude ?? 0.00)
let lon = Double(placemark?.location?.coordinate.longitude ?? 0.00)
print("Lat: \(String(describing: lat)), Lon: \(String(describing: lon))")
let camera = GMSCameraPosition.camera(withLatitude: lat, longitude: lon, zoom: 5)
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: lat, longitude: lon)
marker.title = "\(offerdata.agent_firstname ?? "")"+" \(offerdata.agent_lastname ?? " ")"
marker.iconView?.backgroundColor = .lightGray
marker.userData = data
//amrut
// Clustering
let item = POIItem(position: CLLocationCoordinate2DMake(lat, lon), name: "marker.title" ?? "",data: data)
self.clusterManager.add(item)
//map info views
var image = UIImage()
var currency = String()
if data.currency == "AUD"{
currency = "$\(data.currency ?? "")"
}
else if data.currency == "EUR"{
currency = "€\(data.currency ?? "")"
}
else{
currency = "£\(data.currency ?? "")"
}
let amount = "\(data.offer_amount ?? "")".convertTo2Decimal+" "+currency
//create custom marker accordin to condtions
// "\(agent.offer_amount ?? "")".convertTo2Decimal+" "+"\(agent.currency ?? "AUD")"
if data.auto_approval_on_off == "ON"{
if (data.is_badge_display == "1") {
image = UIImage(named: "blueMarker.png") ?? UIImage()//blue
} else {
image = UIImage(named: "orangeMarker.png") ?? UIImage()//oranfge
}
}
else if (data.is_badge_display == "1") {
image = UIImage(named: "blueMarker.png") ?? UIImage()//blue
} else {
image = UIImage(named: "blackMarker.png") ?? UIImage()//black
}
let customMarker = CustomMarkerView(frame: CGRect(x: 0, y: 0, width: 100, height: 40), image:image , lblText:amount)
// marker.iconView=customMarker
marker.map = self.MapView
self.MapView.camera = camera
}
}
and the same thing i do when in 'GMUClusterRendererDelegate willRenderMarker' delegate method and just uncomment the marker.iconView=customMarker
can anyone please help me what i need to be doing. It will be really helpful
Image for reference
Image for reference2
Two things i want:
1- show clustering for initial load without map icon views
2- show only map icon view and not the pins after cluster rendered/zoom
Please someone help me
I have a problem similar to this. The work around I came up with was to run the clearMarkers function and then re-add the entire array of markers back in using the addMarkers function
I'm still working on this so if I find a better answer I'll update
I am trying to perform an MKLocalSearch.Request() and display the result on my mapView similar to this tutorial however when I do the search the coordinates returned are off center from where they should be. Where the map displays Brooklyn as an overlay in the center of the borough correctly the annotation is far off center to the left. I've noticed that there are two sets of coordinates contained in MKMapItem one the location and the other shown as center when printed to the console. I am not sure how to access the center coordinate but the center coordinate is the correct one in the middle of the screen. How can I access the center coordinate to use as the MKAnnotation's coordinate? Thank you
Search Code
let searchRequest = MKLocalSearch.Request()
searchRequest.naturalLanguageQuery = "brooklyn"
searchRequest.region = MKCoordinateRegion(center: CLLocationCoordinate2DMake(40.758896, -73.985130), latitudinalMeters: 2000, longitudinalMeters: 2000)
let search = MKLocalSearch(request: searchRequest)
search.start { (response, error) in
if let error = error{
print("Error performing search for location")
}
if let response = response{
for item in response.mapItems{
print("map item returned: \(item)")
print("latitude: \(item.placemark.coordinate.latitude) longitude: \(item.placemark.coordinate.longitude)")
let annotation = MKPointAnnotation()
annotation.coordinate = item.placemark.coordinate
annotation.title = item.name
self.mapView.addAnnotation(annotation)
}
}
}
Output
map item returned: Optional(CLCircularRegion (identifier:'<+40.64529796,-73.94483550> radius 14090.15', center:<+40.64529796,-73.94483550>, radius:14090.15m))
latitude: 40.6924599 longitude: -73.9903805
I was able to access the center by casting the region property of MKMapItem's placemark property from CLRegion to CLCircularRegion.
if let response = response{
for item in response.mapItems{
print("map item returned: \(item.placemark)")
if let region = item.placemark.region as? CLCircularRegion{
print("region.center: \(region.center)")
let annotation = MKPointAnnotation()
annotation.coordinate = region.center
annotation.title = item.name
self.mapView.addAnnotation(annotation)
}
}
I am using the Google Maps SDK for iOS - https://developers.google.com/maps/documentation/ios-sdk/marker#use_the_markers_icon_property
Combined with the Maps SDK for iOS Utility Library https://developers.google.com/maps/documentation/ios-sdk/utility/kml-geojson#render-kml-data
I am trying to use the utility library to render a kml file on a map. It mostly works, however the custom icons for the markers are not loading. The markers with their titles, snippets, and locations all load correctly. The only thing that does not work is the custom icon for the marker.
Originally, I thought it was an issue with the utility library, so I spent some time trying to write my own code to go through the kml file and add the custom markers myself. However, before I got too far I noticed that even when I try to add a basic marker with a custom icon, I cannot. This led me to believe it was an issue not with the utility library but with the Maps SDK for iOS. I've tried moving the folder that the image is in, and making sure that the code can see the path to the images, but I cannot get it to work.
This is the code that I have in my project
let path = Bundle.main.path(forResource: testFile, ofType: "kml")
let url = URL(fileURLWithPath: path!)
let kmlParser = GMUKMLParser(url: url)
kmlParser.parse()
let camera = GMSCameraPosition.camera(withLatitude: lat, longitude: long, zoom: zoom)
let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
mapView.mapType = GMSMapViewType.terrain
mapView.isMyLocationEnabled = true
mapView.settings.zoomGestures = true
mapView.settings.myLocationButton = true
let renderer = GMUGeometryRenderer(map: mapView, geometries: kmlParser.placemarks, styles: kmlParser.styles, styleMaps: kmlParser.styleMaps)
renderer.render()
This also does not work
let position = CLLocationCoordinate2D(latitude: lat, longitude: long)
let marker = GMSMarker(position: position)
marker.title = "Test"
marker.icon = UIImage(named: "icon-1")
marker.map = mapView
Thanks in advance for any help
I haven't figured out why the utils library wasn't working, but I did come up with my own fix. It's horrible, but I can come back and make it better later after we've finished adding all the other necessary features to the app and can focus on cleaning up the code .
First, I made a new array of placemarks that had everything except the map markers. I then used this array of placemarks instead of kmlParser.placemarks, so that everything else could be added by the utility library.
//Removing markers without icons
var myIndex = 0
var removed = [GMUGeometryContainer]()
for mark in kmlParser.placemarks{
if(mark.geometry.type != "Point"){
removed.append(kmlParser.placemarks[myIndex])
}
myIndex += 1
}
let renderer = GMUGeometryRenderer(map: mapView, geometries: removed, styles: kmlParser.styles, styleMaps: kmlParser.styleMaps)
renderer.render()
After that, I made my own horrible horrible method that reads the kml file again, and only picks out the placemarks and styles for them and returns an array of Markers.
func addMarkers(fileName:String) -> [GMSMarker]{
var markers = [GMSMarker]()
if let path = Bundle.main.path(forResource: fileName, ofType: "kml"){
do{
let data = try String(contentsOfFile: path, encoding: .utf8)
let myStrings = data.components(separatedBy: .newlines)
var styleToIcon = [String: String]()
var lineNum = 0
for line in myStrings{
//Detecting new style that will be used in placemarks
if line.contains("Style id") && line.contains("normal") && !line.contains("line-"){
let newKey = String(line.split(separator: "\"")[1])
let newValue = String(myStrings[lineNum+4].split(separator: ">")[1].split(separator: "/")[1].split(separator: "<")[0])
styleToIcon[newKey] = newValue
}
//Detecting new placemark on map
else if(line.contains("<Placemark>") && !myStrings[lineNum+2].contains("#line")){
//Get name
var name = myStrings[lineNum+1].split(separator: ">")[1].split(separator: "<")[0]
//Sometimes name has weird CDATA field in it that needs to be removed
if(name.contains("![CDATA")){
name = name.split(separator: "[")[2].split(separator: "]")[0]
}
//Get snippet (description)
var snippet = myStrings[lineNum+2].split(separator: ">")[1].split(separator: "<")[0]
//Sometimes snippet has weird CDATA field in it that needs to be removed
if(snippet.contains("![CDATA")){
snippet = snippet.split(separator: "[")[2].split(separator: "]")[0]
}
//Get style
let style = String(myStrings[lineNum+3].split(separator: ">")[1].split(separator: "#")[0].split(separator: "<")[0] + "-normal")
//Get Coordinates
let coordStringSplit = myStrings[lineNum+6].split(separator: ",")
var lat = 0.0
var long = 0.0
if(coordStringSplit[0].contains("-")){
long = Double(coordStringSplit[0].split(separator: "-")[1])! * -1.0
}else{
long = Double(coordStringSplit[0])!
}
if(coordStringSplit[1].contains("-")){
lat = Double(coordStringSplit[1].split(separator: "-")[1])! * -1.0
}else{
lat = Double(coordStringSplit[1])!
}
//Create marker and add to list of markers
let position = CLLocationCoordinate2D(latitude: lat, longitude: long)
let marker = GMSMarker(position: position)
marker.title = String(name)
marker.snippet = String(snippet)
marker.icon = UIImage(named: styleToIcon[style]!)
markers.append(marker)
}
lineNum += 1
}
}catch{
print(error)
}
}
return markers
}
This is so heavily related to how my kml files look that I doubt it will help anyone else, but I thought I should post it just in case.
Now that we have that method, all we need to do is go back to where we were rendering all of the kml data and render those markers on the map
//Adding markers with icons
let newMarkers = addMarkers(fileName: courseName)
for mark in newMarkers{
mark.map = mapView
}
I also had to go through my kml files manually and fix some of the image names, but that wasn't a big deal. Even if the utility library worked I would need to do that because the utility library only does kml files and not kmz, so each kml file references the same folder for images and uses the same names for images. It's fine, only takes a few minutes per file. Would be nice if there was a kmz library but oh well.
Hopefully this helps someone else, and hopefully I can find the real solution soon (unless its a problem with the utility library in which case hopefully it's fixed soon).
//call method by passing ;
if userLocation.coordinate.latitude != 0.0 && userLocation.coordinate.longitude != 0.0
{
self.updateCurrentPositionMarker(currentLocation: CLLocation(latitude: userLocation.coordinate.latitude, longitude:userLocation.coordinate.longitude))
}
//methods
func updateCurrentPositionMarker(currentLocation: CLLocation) {
self.currentPositionMarker.map = nil
self.currentPositionMarker = GMSMarker(position: currentLocation.coordinate)
if self.imageDataUrl != ""
{
let camera: GMSCameraPosition = GMSCameraPosition.camera(withLatitude: currentLocation.coordinate.latitude, longitude: currentLocation.coordinate.longitude, zoom: 18.0)
self.mapView.camera = camera
//self.imageDataUrl == image to show
self.currentPositionMarker.iconView = self.drawImageWithProfilePic(urlString:self.imageDataUrl,image: UIImage.init(named: “backgroungImage”)!)
self.currentPositionMarker.zIndex = 1
}
self.currentPositionMarker.map = self.mapView
self.mapView.reloadInputViews()
}
func drawImageWithProfilePic(urlString:String, image: UIImage) -> UIImageView {
let imgView = UIImageView(image: image)
imgView.frame = CGRect(x: 0, y: 0, width: 90, height: 90)
let picImgView = UIImageView()
picImgView.sd_setImage(with:URL(string: urlString))
picImgView.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
imgView.addSubview(picImgView)
picImgView.center.x = imgView.center.x
picImgView.center.y = imgView.center.y-10
picImgView.layer.cornerRadius = picImgView.frame.width/2
picImgView.clipsToBounds = true
imgView.setNeedsLayout()
picImgView.setNeedsLayout()
// let newImage = imageWithView(view: imgView)
// return newImage
return imgView
}
I am trying to show multiple location using Google maps, the code showing only one location. I am using for loop. I checked the code using MKMapView and it's working.
Here is the code:
let dict = [self.jsonElement]
for dicts in dict {
let latiCon = (dicts.value(forKey: "lati") as! NSString).doubleValue
let longiCon = (dicts.value(forKey: "longi") as! NSString).doubleValue
// Create a GMSCameraPosition that tells the map to display the
// coordinate -33.86,151.20 at zoom level 6.
let camera = GMSCameraPosition.camera(withLatitude: latiCon, longitude: longiCon, zoom: 6.0)
let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
self.view = mapView
// Creates a marker in the center of the map.
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: latiCon, longitude: longiCon)
marker.title = "Sydney"
marker.snippet = "Australia"
marker.map = mapView
}
I need to show multiple locations as I said, I have a look to relative answers but I did not find anything match with my question.
this code
let camera = GMSCameraPosition.camera(withLatitude: latiCon, longitude: longiCon, zoom: 6.0)
let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
self.view = mapView
makeing a new mapView every time in loop so it's natural what you get.
a new mapview + one marker .
move this code outside loop or delete it if you already have a mapview declared before.
I use a Google Maps Api for maps and markers.
I enable accessibility for markers by setting: mapView.accessibilityElementsHidden = false
Now all my custom markers on map have accessibility ids like: myappname.GMSPlaceMarker_somenumbers, for example myappname.GMSPlaceMarker_0x600000170200.
How could i set a one accessibilityIdentifier for all pins, for example Map pin?
I already tried:
marker.accessibilityLabel = "Map pin" but it set label value, not id
marker.title = "Map pin" nothing changes
marker.setValue("Map pin", forKey: "accessibilityIdentifier") nothing changes
My marker is let marker = GMSPlaceMarker() where class GMSPlaceMarker: GMSMarker
try this,
func markPoints() {
var annotationCoord : CLLocationCoordinate2D = CLLocationCoordinate2D()
annotationCoord.latitude = (selectedLocation.latitude as NSString).doubleValue
annotationCoord.longitude = (selectedLocation.longitude as NSString).doubleValue
let annotationPoint: MKPointAnnotation = MKPointAnnotation()
annotationPoint.coordinate = annotationCoord
annotationPoint.title = selectedLocation.name
annotationPoint.subtitle = "Anand: 7348858742"
theMap.addAnnotation(annotationPoint)
}
If you are using swift 4 try this one,
var destionationMarker: GMSMarker!
func setupDriverMarker(coordinate: CLLocationCoordinate2D) {
destionationMarker = GMSMarker(position: coordinate)
for pin: GMSMarker in self.DestinationMarkerArray {
if pin.userData as! String == "drivermarker" {
pin.map = nil
}
}
destionationMarker.title = "Your Title"
destionationMarker.appearAnimation = GMSMarkerAnimation.pop
let images = #imageLiteral(resourceName: "ic_map_marker")
destionationMarker.icon = images
destionationMarker.userData = "drivermarker"
destionationMarker.opacity = 1
destionationMarker.map = journeyMapView
}
Implementing like this
DriverLocation = CLLocationCoordinate2D(latitude: 21.2362546, longitude: 72.8751862)
setupDriverMarker(coordinate: DriverLocation)
I had a similar issue as well, there is no accessibilityIdentifier for GMSMarker. What I did, setting either an accessibilityIdentifier to icon or iconView such as:
marker.icon?.accessibilityIdentifier = "something" or
marker.iconView?.accessibilityIdentifier = "something"