在 MapBox Android 与 iOS 上显示 GeoJSON
Display GeoJSON on MapBox Android vs iOS
我使用 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 地图框
安卓 Mapbox
一种选择是使用 MGLShapeSource work with GeoJSON data。然后,您可以将其用作 MGLFillStyleLayer 的来源。
您可能还想研究使用 Android 和 iOS SDK 最新测试版中引入的数据驱动样式。对于 iOS,您可以使用 MGLSourceStyleFunction
和 fillColor
on your MGLFillStyleLayer
来根据特征属性设置样式。
这是我最终做到的:
首先,我解析 JSON 以获得每种颜色和关联值,然后我为每种颜色创建一个 FillStyleLayer 并设置 predicate 属性以将颜色限制为特定值。
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")
}
我使用 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)
}
}
}
}
}
}
一种选择是使用 MGLShapeSource work with GeoJSON data。然后,您可以将其用作 MGLFillStyleLayer 的来源。
您可能还想研究使用 Android 和 iOS SDK 最新测试版中引入的数据驱动样式。对于 iOS,您可以使用 MGLSourceStyleFunction
和 fillColor
on your MGLFillStyleLayer
来根据特征属性设置样式。
这是我最终做到的: 首先,我解析 JSON 以获得每种颜色和关联值,然后我为每种颜色创建一个 FillStyleLayer 并设置 predicate 属性以将颜色限制为特定值。
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")
}