Comments (31)
FYI: we are working on making marker customization easier. Will have a release out end of this week or earlier next week. So stay tuned.
from google-maps-ios-utils.
from google-maps-ios-utils.
What you can do is extend GMUDefaultClusterRenderer and override this method
- (GMSMarker *)markerWithPosition:(CLLocationCoordinate2D)position
from:(CLLocationCoordinate2D)from
userData:(id)userData
clusterIcon:(UIImage *)clusterIcon
animated:(BOOL)animated
This is where the marker is actually created. I've included some sample code here. Please note the new code is between the "// new code" markers. Let us know how you go. We will plan to make a better API for this use case in a later release.
CLLocationCoordinate2D initialPosition = animated ? from : position;
GMSMarker *marker = [GMSMarker markerWithPosition:initialPosition];
marker.userData = userData;
if (clusterIcon != nil) {
marker.icon = clusterIcon;
marker.groundAnchor = CGPointMake(0.5, 0.5);
}
// new code starts here.
else {
// this is new code for customizing individual markers
marker.icon = [self getCustomIconForItem:userData]; // stub method
marker.title = [self getCustomTitleItem:userData]; // stub method
}
// new code ends here.
marker.map = _mapView;
if (animated) {
[CATransaction begin];
[CATransaction setAnimationDuration:kGMUAnimationDuration];
marker.layer.latitude = position.latitude;
marker.layer.longitude = position.longitude;
[CATransaction commit];
}
from google-maps-ios-utils.
@mountainvat could you provide a swift example for this GMUDefaultClusterRenderer delegate?
from google-maps-ios-utils.
You can safely cast userData to your cluster item object. So I'd imagine something like this:
- (NSString *)getCustomTitleItem:(id)userData {
POIItem *item = userData;
return item.name;
}
from google-maps-ios-utils.
@BeetLab you can use the event to customize your mark before it's added to the map. See https://github.com/googlemaps/google-maps-ios-utils/blob/master/CustomMarkers.md for an example of how to use it.
from google-maps-ios-utils.
@mountainvat Hello,
in this function:
func renderer(_ renderer: GMUClusterRenderer, willRenderMarker marker: GMSMarker) {}
makrer.iconView
is always nil
even if I set it up before like this:
func renderer(_ renderer: GMUClusterRenderer, willRenderMarker marker: GMSMarker) {
// Check if marker or cluster
if marker.userData is PlaceMarker {
if let userData = marker.userData as? PlaceMarker {
marker.iconView = MarkerView(caption: userData.caption)
}
marker.groundAnchor = CGPoint(x: 0.5, y: 1)
marker.isFlat = true
marker.appearAnimation = kGMSMarkerAnimationPop
} else {
// Apply custom view for cluster
marker.iconView = ClusterViewIcon()
// Show clusters above markers
marker.zIndex = 1000;
marker.groundAnchor = CGPoint(x: 0.5, y: 1)
marker.isFlat = true
marker.appearAnimation = kGMSMarkerAnimationPop
}
}
how can one implement a guard
to only setup iconView
and other marker
properties only when the marker is rendered for the first time? otherwise it is just a waste of resources.. (and also the animation happens on every zoom level change)
from google-maps-ios-utils.
@mountainvat This works for changing all of individual markers to the same icon and title, but I do not know how to use this code to change only some of individual markers. I would like to set the icon and the title of markers depending on a variable stored in my custom GMUClusterItem. Is there a way to do this too?
from google-maps-ios-utils.
one way you can do replace this code:
marker.icon = [self getCustomIconForItem:userData]; // stub method
marker.title = [self getCustomTitleItem:userData]; // stub method
with
marker.icon = [self getCustomIconForItem:userData] ? : marker.icon; // stub method
marker.title = [self getCustomTitleItem:userData] ? : marker.title; // stub method
and in the getCustomXXX method, you'd return nil if the item should not be customized.
Hope it helps.
from google-maps-ios-utils.
@mountainvat I am sorry, but I'm not familiar with Objective C and don't know how I should replace [self getCustomIconForItem:userData]
and [self getCustomTitleItem:userData]
.
If I want to title my marker with POIItem's name (from https://developers.google.com/maps/documentation/ios-sdk/utility/marker-clustering), for example, should I call userData's name variable?
`
/// Point of Interest Item which implements the GMUClusterItem protocol.
class POIItem: NSObject, GMUClusterItem {
var position: CLLocationCoordinate2D
var name: String!
init(position: CLLocationCoordinate2D, name: String) {
self.position = position
self.name = name
}
}`
from google-maps-ios-utils.
@mountainvat I tried to put your code in GMSDefaultClusterRenderer.m, but it says use of undeclared identifier. Should I move POIItem class to Clustering folder that has all Google-Maps-IOS-Utils classes?
from google-maps-ios-utils.
I would not put the code inside GMSDefaultClusterRenderer.m. I'd rather extend it in your own application's classes. Since the custom renderer lives in your app's target it should have access yo your GMUClusterItem classes. So you could do something like this:
@interface MyClusterRenderer : GMSDefaultClusterRenderer
@end
@implementation MyClusterRenderer
- (NSString *)getCustomTitleItem:(id)userData {
YourOwnGMUClusterItemClass *item = userData;
return item.name;
}
@end
from google-maps-ios-utils.
@mountainvat That makes sense. Apparently, I did not read your very first answer that said to extend GMSDefaultClusterRenderer. However, it fails to build. ("Command failed due to signal: Segmentation fault: 11"
This is what I have for my custom renderer:
#import <Foundation/Foundation.h>
#import "CustomRenderer.h"
#import "MyProjectName-swift.h"
// Animation duration for marker splitting/merging effects.
static const double kGMUAnimationDuration = 0.5; // seconds.
@implementation CustomRenderer
// Map view to render clusters on.
__weak GMSMapView *_mapView;
- (NSString *)getCustomTitleItem:(id)userData {
MyOwnClusterItemClass *item = userData;
return item.title;
}
- (GMSMarker *)markerWithPosition:(CLLocationCoordinate2D)position
from:(CLLocationCoordinate2D)from
userData:(id)userData
clusterIcon:(UIImage *)clusterIcon
animated:(BOOL)animated {
CLLocationCoordinate2D initialPosition = animated ? from : position;
GMSMarker *marker = [GMSMarker markerWithPosition:initialPosition];
marker.userData = userData;
if (clusterIcon != nil) {
marker.icon = clusterIcon;
marker.groundAnchor = CGPointMake(0.5, 0.5);
} else {
marker.title = [self getCustomTitleItem:userData] ? : marker.title;
}
marker.map = _mapView;
if (animated) {
[CATransaction begin];
[CATransaction setAnimationDuration:kGMUAnimationDuration];
marker.layer.latitude = position.latitude;
marker.layer.longitude = position.longitude;
[CATransaction commit];
}
return marker;
}
@end
Do you know what is causing this error?
from google-maps-ios-utils.
I cannot reason why it would cause a Segmentation fault. Do you have a stacktrace?
Anyway I can see a problem with your code (maybe not related): the _mapView instance var is always nil. What you also need to do is override initWithMapView to capture the mapView into your private _mapView variable.
Add this method to your new derived class:
- (instancetype)initWithMapView:(GMSMapView *)mapView
clusterIconGenerator:(id<GMUClusterIconGenerator>)iconGenerator {
self = [super initWithMapView:mapView clusterIconGenerator:iconGenerator];
if (self) {
_mapView = mapView;
}
}
from google-maps-ios-utils.
@s-p-a-r-k : Any luck with this? Can we close the ticket?
from google-maps-ios-utils.
@mountainvat Sorry, I haven't had a chance to try it. But you can close it. I will tell you if it works. Thank you very much for your help!
from google-maps-ios-utils.
@mountainvat I've tried to override GMUDefaultClusterRenderer, but I got this error.
Duplicate definition of category 'GoogleMaps' on interface 'GMSCoordinateBounds'
from google-maps-ios-utils.
I must be numb-skulled, I'm trying to over-ride GMUDefaultClusterRenderer to achieve more dynamicity in my custom markers without having to edit the main file. I copied the code from the original file to a new class as previously aforementioned in the previous post. Although I'm now receiving mach-o linker errors after setting it up. Deleting my custom class completely removes the errors. I've managed to change the marker fine, but am struggling on how to do it "the right way".
from google-maps-ios-utils.
I have gone through the new GMUClusterRendererDelegate
How can I use this in swift, I have to show markerimage(which would again be changing to different conditions) and have a label at the bottom of this marker. In Swift, I have used func renderer(renderer: GMUClusterRenderer, markerForObject object: AnyObject) -> GMSMarker
but it is not getting called before placing the marker so that I can change images on that?
from google-maps-ios-utils.
If you update to version 1.1.x there should be new events for before and after the markers are added to map. Please see this post for more information: https://github.com/googlemaps/google-maps-ios-utils/blob/master/CustomMarkers.md
from google-maps-ios-utils.
@jamesynotnot actually wanted to translate somehow this file
https://github.com/googlemaps/google-maps-ios-utils/blob/master/app/CustomMarkerViewController.m
Which has the functions to make this view happen.
Because im in the same position to have a json with names and images urls.
from google-maps-ios-utils.
from google-maps-ios-utils.
@jamesynotnot not the best way 😞
from google-maps-ios-utils.
from google-maps-ios-utils.
Hey guys, just came across this during my PR to support clustering with google maps in Titanium (here). A convenient way would be to just subclass it and use the protocol to create everything. Unfortunately, methods like markerWithPosition:from:userData:clusterIcon:animated:
are not in the public interface, so they won't be suggested. That would be one of the improvements.
Additionally to that, things links handling the mapView reference should be solved using a reference to the super class, so we don't need to declare own initializers. Not sure if I can help here, but this sounds like a doable change! :-)
from google-maps-ios-utils.
@mountainvat - But what about that :
/**
- Raised when a marker (for a cluster or an item) is about to be added to the map.
- Use the marker.userData property to check whether it is a cluster marker or an
- item marker.
*/
- (void)renderer:(id)renderer willRenderMarker:(GMSMarker *)marker;
in @protocol GMUClusterRendererDelegate?
from google-maps-ios-utils.
How to load this cluster GMSMapview into custom view like below ?
- (void)loadView {
GMSCameraPosition *camera =
[GMSCameraPosition cameraWithLatitude:kCameraLatitude longitude:kCameraLongitude zoom:10];
_mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
self.myMapView = _mapView;
}
currently its loading only to self.view
from google-maps-ios-utils.
How many different cluster views do you have? If you have only 1 custom view (shared by many clusters) then I'd suggest return the same instance in ClusterViewIcon() so that the view is only rendered once.
In addition, this event is only raised once when the marker is brought into view unless a recluster happens (say on a zoom level change). For this maybe raise a separate issue and we will see if we can address it in the coming release.
from google-maps-ios-utils.
I did it before - stored a pre-created view in a var
, and assigned this var
to the iconView
, thus the view was rendered only once. But now I need to setup captions. Each marker has it's own caption. So I can't use 1 view for every marker.
Exactly. On the zoom level change. If nothing changes (i.e. no clustering / declustering happens), we recreate already rendered markers and waste resources.
from google-maps-ios-utils.
If don't call func renderer:
implementation GMUClusterRendererDelegate
renderer.delegate = self
from google-maps-ios-utils.
@mountainvat Can you help with my problem? I am done with the clustering. The markers are clustered. but, it is not showing the Cluster count. Any help will be appreciable.
from google-maps-ios-utils.
Related Issues (20)
- The automated release is failing 🚨 HOT 1
- snippet-bot full scan
- 4.2.0 version not building cause of missing xframework file HOT 2
- SPM error cannot resolve it. HOT 2
- Clustering: add setter for clusterDistancePoints in the GMUNonHierarchicalDistanceBasedAlgorithm.m HOT 1
- Clustering : Cluster Markers do not initially hide their items on the map HOT 1
- 4.2.2 does not allow updating to latest GoogleMaps (8.x) HOT 13
- TipKit: when adding popover tip to some view on top of GMSMapView tip starts flickering on every map move HOT 1
- Google maps utils compiler error in new Xcode Version 15.0.1 HOT 44
- empty field MinimumOSVersion for internal FB frameworks causes failure on uploading to App Store Connect with Xcode 15.3 HOT 4
- Xcode 15.3 and App store connect issue HOT 2
- Cannot find type 'GMUWeightedLatLng' in scope HOT 2
- I want display multiple cluster images based on markers data HOT 1
- Support App Privacy Manifests HOT 4
- GoogleMaps don't compile at Mac's (is this ever getting fixed?) HOT 1
- Failed to build module 'GoogleMapsUtils Xcode HOT 2
- GMSMapViewDelegate didTapMyLocationButton no zoom HOT 1
- Failed to build module 'GoogleMapsUtils'; this SDK is not supported by the compiler (the SDK is built with 'Apple Swift version 5.5.2 (swiftlang-1300.0.47.5 clang-1300.0.29.30)', while this compiler is 'Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4)'). Please select a toolchain which matches the SDK. HOT 4
- Invalid Bundle. The bundle Frameworks/GoogleMapsUtils.framework does not support the minimum OS Version specified in the Info.plist HOT 5
- Status of this project HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from google-maps-ios-utils.