使用适用于 iOS 的 Google Maps SDK 优化自定义标记图像性能

Posted

技术标签:

【中文标题】使用适用于 iOS 的 Google Maps SDK 优化自定义标记图像性能【英文标题】:Optimising custom marker image performance with Google Maps SDK for iOS 【发布时间】:2014-10-22 17:27:56 【问题描述】:

我最近将 Google Maps for ios SDK 整合到 iOS 应用程序中。这个应用程序旨在检索飞机的位置(包括飞机型号、纬度/经度、速度 - 飞机的基本值),然后将它们绘制在谷歌地图上。

现在,最近,API(我正在使用的那个)返回的飞机数量翻了一番,几乎翻了三倍。之前我每次尝试运行该应用程序时都没有遇到任何问题,它会崩溃,并出现以下错误:

((null)) was false: Reached the max number of texture atlases, can not allocate more.

我在 SDK 的 Google 代码上找到了这个问题页面:https://code.google.com/p/gmaps-api-issues/issues/detail?id=5756 - 在这里,我相信我的崩溃问题归结于我正在使用的自定义标记图像的数量。每个飞机模型都有不同的图像,这些图像在渲染时加载,并将 UIImage 分配给 GMSMarker。

现在,我遇到的问题是大量结果,我遇到了这个崩溃。同时,我还希望每个标记都有单独的图像。

我的问题是,有没有一种方法可以代替为每个标记分配特定飞机的 UIImage,而可以参考每个图像以优化性能?

感谢您的帮助,如果我没有说清楚,请告诉我!

【问题讨论】:

【参考方案1】:

再次遇到问题后回答我自己的问题。

问题似乎是我为每个标记分配了一个单独的 UIImage 实例。这意味着当我在 GMSMapView 实例上绘制标记时,每个标记都有一个单独的 UIImage。此处简要描述:Customize the marker image - Google Maps SDK for iOS。

如果您使用相同的图像创建多个标记,请为每个标记使用相同的 UIImage 实例。这有助于在显示许多标记时提高应用程序的性能。

我正在遍历对象列表以创建每个标记:

for (int i = 0; i < [array count]; i++) 
    UIImage *image = [UIImage imageWithContentsOfFile:@"image.png"];
    CLLocationCoordinate2D position = CLLocationCoordinate2DMake(10, 10);
    GMSMarker *marker = [GMSMarker markerWithPosition:position];
    marker.title = @"Hello World";
    marker.icon = image;
    marker.map = mapView_;

所以在这里,我将图像复制到每个标记。这占用了不必要的资源。我的解决方案:

UIImage *image = [UIImage imageWithContentsOfFile:@"image.png"];

for (int i = 0; i < [array count]; i++) 
    CLLocationCoordinate2D position = CLLocationCoordinate2DMake(10, 10);
    GMSMarker *marker = [GMSMarker markerWithPosition:position];
    marker.title = @"Hello World";
    marker.icon = image;
    marker.map = mapView_;

在 for 循环之外定义 UIImage 实例意味着图像是从每个标记引用的,而不是为每个标记重新渲染的。此后内存使用量大大降低。

【讨论】:

【参考方案2】:

我的解决方案; ((null)) 为假:已达到纹理图集的最大数量,无法分配更多。

您在创建标记时将位置信息保留在线程之外。

OperationQueue.main.addOperation 
    let coordinates = CLLocationCoordinate2D(latitude:LatData!, longitude: longData!)
    let marker = GMSMarker(position: coordinates)
    marker.icon = GMSMarker.markerImage(with: .blue)

    for i in 0 ... self.DemandLong.count 
        marker.infoWindowAnchor = CGPoint(x: 0, y: 5)
        marker.map = self.MyExploreView

        marker.accessibilityLabel = "\(i)" //Marker Label
        print("Location Marker i:\(i)")
    

【讨论】:

请澄清答案,当您说“将位置信息保留在线程之外”时,您的意思是在for循环之外吗? 不,for循环上的结构。【参考方案3】:
Instead of setting marker's iconView, set marker's icon. That too initialize the image outside of for loop, as below

func displayMarkers() 
let iconImage = UIImage(named: "locationgreen")
for partner in partners 
    let lat : Double = Double(partner.location?.coordinates![1] ?? 0)
    let lng : Double = Double(partner.location?.coordinates![0] ?? 0)

    let position = CLLocationCoordinate2D(latitude: lat, longitude: lng)
    let marker = GMSMarker(position: position)
    marker.title = partner.name
    marker.icon = iconImage
    

【讨论】:

以上是关于使用适用于 iOS 的 Google Maps SDK 优化自定义标记图像性能的主要内容,如果未能解决你的问题,请参考以下文章

适用于 iOS 的 Google Maps SDK 不断增加内存使用量

适用于 iOS 的 Google Maps SDK - 折线

google-maps-sdk-ios - 适用于 iOS 的 Google 地图 1.4.3 的 arm 7/iphone 5 问题

带有适用于 iOS 的 Google Maps SDK 的可拖动标记

适用于 iOS 的 Google Maps SDK 要求 GoogleMaps.bundle 成为“复制捆绑资源”下目标的一部分

发布到 App Store 后,适用于 iOS 的 Google Maps SDK 崩溃