在MapBox Android和iOS上显示GeoJSON

时间:2017-03-07 15:07:49

标签: ios swift mapbox geojson

我使用mapbox在iOS和Android应用上显示geojson。

同一个geojson在两个平台上的显示方式都不同。我认为某些形状隐藏了iOS上的其他形状。

mapbox ios sdk上没有MGLGeoJSONSource,看起来就像是删除了它。因此,实现相同的结果需要更长的时间。

也许有人有更好的方法来点缀它?

这是我的java代码:

JSONArray features = json.getJSONArray("features");
for (int i = 0; i < features.length(); i++) {
    JSONObject feature = features.getJSONObject(i);

    GeoJsonSource geoJsonSource = new GeoJsonSource(i, feature.toString());

    JSONObject properties = feature.getJSONObject("properties");
    int rounded_value = (int)Math.round(properties.getDouble("value"););

    list_value_geojson.add(new AbstractMap.SimpleEntry<>(rounded_value, geoJsonSource));
}

for (int i=0; i < list_value_geojson.size(); i++){
    Map.Entry<Integer, GeoJsonSource> entry = list_value_geojson.get(i);

    mapboxMap.addSource(entry.getValue());

    FillLayer fillLayer = new FillLayer(entry.getValue().getId(), entry.getValue().getId());
    fillLayer.setProperties(PropertyFactory.fillColor(Color.parseColor(hashMapColors.get(entry.getKey()))));

    mapboxMap.addLayer(fillLayer);
}

这是我的Swift代码:

if let features = jsonDict["features"] as? NSArray {
    var sourceIndex = 0
    for feature in features {
        if let feature = feature as? NSDictionary {
            if let geometry = feature["geometry"] as? NSDictionary {
                let coordinates_array_of_array = geometry["coordinates"] as! NSArray
                for coordinates_array in coordinates_array_of_array{

                    var coordinates_collection : [CLLocationCoordinate2D] = []

                    let locations = coordinates_array as? [[Double]]

                    for location in locations! {
                        // Make a CLLocationCoordinate2D with the lat, lng
                        let coordinate = CLLocationCoordinate2D(latitude: location[1], longitude: location[0])

                        // Add coordinate to coordinates array
                        coordinates_collection.append(coordinate)
                    }

                    if let properties = feature["properties"] as? NSDictionary {
                        let mglpf = MGLPolygonFeature(coordinates: coordinates_collection, count: UInt(coordinates_collection.count))


                        mglpf.title = String(properties["value"] as! Int32)

                        mglpf.attributes = ["color":getColorFromValue(value: mglpf.title!)]

                        let source = MGLShapeSource(identifier: "shapeSource"+String(sourceIndex), features: [mglpf], options: nil)

                        mapbox?.style?.addSource(source)
                        sourceIndex = sourceIndex + 1

                        let layer = MGLFillStyleLayer(identifier: "layer"+String(sourceIndex), source: source)
                        layer.fillColor = MGLStyleValue<UIColor>(rawValue: Util.hexStringToUIColor(hex: getColorFromValue(value: mglpf.title!)))
                        mapbox?.style?.addLayer(layer)
                    }

                }
            }
        }
    }
}

iOS iOS Mapbox

Android Andorid Mapbox

2 个答案:

答案 0 :(得分:2)

一种选择是使用MGLShapeSource到work with GeoJSON data。然后,您可以将其用作MGLFillStyleLayer的源。

您可能还希望了解使用Android和iOS SDK最新测试版中引入的数据驱动样式。对于iOS,您可以使用MGLSourceStyleFunctionfillColor on your MGLFillStyleLayer根据功能属性设置样式。

答案 1 :(得分:1)

以下是我最终的成就: 首先我解析JSON以获取每种颜色和关联值,然后我为每种颜色创建一个FillStyleLayer并设置谓词属性以将颜色限制为特定值。

let url = URL(fileURLWithPath: jsonPath)
do {  
// Load and serialize the GeoJSON into a dictionary filled with properly-typed objects
if let jsonDict = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [String : AnyObject] {

    // parse json to Get all colors with their value and put it in the dictionnary
    if let features = jsonDict["features"] as? NSArray {
        for feature in features {
            if let feature = feature as? NSDictionary {
                if let properties = feature["properties"] as? NSDictionary {
                    let color = properties["color"] as! String
                    let value = properties["value"] as! Double

                    if colorByValueArray.index(forKey: value) == nil {
                        colorByValueArray[value] = color
                    }
                }
            }
        }
    }

    //Add GeoJSON to map source
    let mglss = MGLShapeSource(identifier: DrawGeoJSON.TAG_SOURCE_PREFIX + shape_type, url: NSURL(fileURLWithPath: jsonPath) as URL, options: nil)
    mapbox.style?.addSource(mglss)

    //Create color rules with filllayer
    //This will create a fillLayer for each different value/color
    //Some values from geoJSON are not int value. == operator doesn't work with this float value so I had to use < > operators
    for colorDic in colorByValueArray {
        let mglfsl = MGLFillStyleLayer(identifier: DrawGeoJSON.TAG_LAYER_PREFIX + shape_type + String(colorDic.key), source: mglss)
        mglfsl.sourceLayerIdentifier = DrawGeoJSON.TAG_SOURCE_PREFIX + shape_type
        mglfsl.predicate = NSPredicate(format: "value < %d AND value >= %d", Int(colorDic.key)+1, Int(colorDic.key))
        mglfsl.fillColor = MGLStyleValue<UIColor>(rawValue: Util.hexStringToUIColor(hex: colorDic.value))
        mapbox.style?.addLayer(mglfsl)
    }

}
}
catch
{
    print("GeoJSON parsing failed")
}