GithubHelp home page GithubHelp logo

Comments (31)

mountainvat avatar mountainvat commented on July 25, 2024 8

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.

jamesynotnot avatar jamesynotnot commented on July 25, 2024 8

from google-maps-ios-utils.

mountainvat avatar mountainvat commented on July 25, 2024 6

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.

kwstasna avatar kwstasna commented on July 25, 2024 4

@mountainvat could you provide a swift example for this GMUDefaultClusterRenderer delegate?

from google-maps-ios-utils.

mountainvat avatar mountainvat commented on July 25, 2024 1

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.

mountainvat avatar mountainvat commented on July 25, 2024 1

@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.

grundmanise avatar grundmanise commented on July 25, 2024 1

@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.

s-p-a-r-k avatar s-p-a-r-k commented on July 25, 2024

@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.

mountainvat avatar mountainvat commented on July 25, 2024

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.

s-p-a-r-k avatar s-p-a-r-k commented on July 25, 2024

@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.

s-p-a-r-k avatar s-p-a-r-k commented on July 25, 2024

@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.

mountainvat avatar mountainvat commented on July 25, 2024

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.

s-p-a-r-k avatar s-p-a-r-k commented on July 25, 2024

@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.

mountainvat avatar mountainvat commented on July 25, 2024

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.

mountainvat avatar mountainvat commented on July 25, 2024

@s-p-a-r-k : Any luck with this? Can we close the ticket?

from google-maps-ios-utils.

s-p-a-r-k avatar s-p-a-r-k commented on July 25, 2024

@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.

vjerryv avatar vjerryv commented on July 25, 2024

@mountainvat I've tried to override GMUDefaultClusterRenderer, but I got this error.

Duplicate definition of category 'GoogleMaps' on interface 'GMSCoordinateBounds'

screenshot 2016-09-22 11 40 37

from google-maps-ios-utils.

astrolope avatar astrolope commented on July 25, 2024

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.

unlimitedK avatar unlimitedK commented on July 25, 2024

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.

mountainvat avatar mountainvat commented on July 25, 2024

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.

kwstasna avatar kwstasna commented on July 25, 2024

@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.

jamesynotnot avatar jamesynotnot commented on July 25, 2024

from google-maps-ios-utils.

kwstasna avatar kwstasna commented on July 25, 2024

@jamesynotnot not the best way 😞

from google-maps-ios-utils.

jamesynotnot avatar jamesynotnot commented on July 25, 2024

from google-maps-ios-utils.

hansemannn avatar hansemannn commented on July 25, 2024

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.

BeetLab avatar BeetLab commented on July 25, 2024

@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.

prsreejith avatar prsreejith commented on July 25, 2024

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.

mountainvat avatar mountainvat commented on July 25, 2024

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.

grundmanise avatar grundmanise commented on July 25, 2024

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.

miragessee avatar miragessee commented on July 25, 2024

@jamesynotnot

If don't call func renderer:

implementation GMUClusterRendererDelegate

renderer.delegate = self

from google-maps-ios-utils.

Prathapreddy26 avatar Prathapreddy26 commented on July 25, 2024

@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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.