GeoJSON onClickListener无法处理多边形

时间:2016-09-11 11:44:27

标签: java android google-maps onclicklistener geojson

更新

最初的问题在线下,但我已经进一步研究了这个问题并添加了一些额外的信息。

首先,发生错误的原因是因为GeoJSON文件包含多边形,这些多边形被归类为" MultiPolygons"。它们基本上是一起定义的多个多边形。 (想象一下,你试图将像希腊这样的国家代表文件中的一个单位,该国家本身由许多岛屿组成,因此需要" MultiPolygons")

我尝试使用GeoJSON文件编写下面的代码,我使用一个简单的多边形定义为" Polygon" (不是" Multipolygon")代码可以正常工作。

现在问题变成了......有没有办法在MultiPolygons上使用onclick方法,如果有的话,如何实现呢?

如果我有运气,我会继续测试和发布,否则任何输入都会受到赞赏。

我一直在寻找将geoJSON文件添加到谷歌地图并在Android应用程序中与它进行交互。

Google有一个地图实用程序库来帮助实现这一目标:

https://developers.google.com/maps/documentation/android-api/utility/geojson

我成功导入了geojson信息(在本例中是带有属性的MultiPolygons),并且可以从java程序中提取特征属性等。

我想要采取的下一步是能够点击多边形并提取相同的属性信息,或者为点击的"功能添加新的多边形#34;。

我在Google" GeoJSONDemoActivity"中找到了代码。应该在点击时显示属性的吐司。除了它会引发错误。

我应该指出我对编码很新,我可能会遗漏一些明显的东西,但我真的看不到它。

以下是问题的代码:

all_rough.setOnFeatureClickListener(new GeoJsonLayer.GeoJsonOnFeatureClickListener() {
            @Override
            public void onFeatureClick(GeoJsonFeature feature) {
                Toast.makeText(EuroMap.this,
                        "Feature clicked: " + feature.getProperty("geounit"),
                        Toast.LENGTH_SHORT).show();
            }
        });

我还应该指出,如果你删除:

+ feature.getProperty("geounit")

代码可以正常工作,点击后你会看到"功能点击:"

这是错误:

09-11 11:20:48.759 2814-2814/com.thetestspecimen.worldmap E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.thetestspecimen.worldmap, PID: 2814
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.google.maps.android.geojson.GeoJsonFeature.getProperty(java.lang.String)' on a null object reference
at com.thetestspecimen.worldmap.EuroMap$1.onFeatureClick(EuroMap.java:135)
at com.google.maps.android.geojson.GeoJsonLayer$1.onPolygonClick(GeoJsonLayer.java:97)
at com.google.android.gms.maps.GoogleMap$14.zza(Unknown Source)
at com.google.android.gms.maps.internal.zzz$zza.onTransact(Unknown Source)
at android.os.Binder.transact(Binder.java:387)
at yr.a(:com.google.android.gms.DynamiteModulesB:82)
at maps.ad.Z.t(Unknown Source)
at maps.D.m.a(Unknown Source)
at maps.D.l.a(Unknown Source)
at maps.V.u.d(Unknown Source)
at maps.V.P.onSingleTapConfirmed(Unknown Source)
at maps.z.e$b.onSingleTapConfirmed(Unknown Source)
at maps.z.c$a.handleMessage(Unknown Source)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

我还可以确认该功能" geounit"存在于geojson中,属性(在这种情况下)是" England"。我已经使用以下代码对其进行了测试并且它可以正常工作(代码更改了多边形颜色,并输出"消息:英格兰"在日志中):

for (GeoJsonFeature feature : all_rough.getFeatures()) {
           if (feature.getProperty("geounit").equals("England")) {
                feature.setPolygonStyle(englandStyle);
                String country = feature.getProperty("geounit");
                Log.d("myTag", "Message: " + country);

            } else {
                 Log.d("myTag", "Message: Failure");
            }
        }

只是为了向您提供我在GeoJSON文件和完整活动下面提供的所有信息:

以GeoJSON

{
"type": "FeatureCollection",
"crs": { "type": "name", "properties": { "name":    "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "scalerank": 1, "featurecla": "Admin-0  map unit", "labelrank": 5.0, "sovereignt": "United Kingdom", "sov_a3": "GB1", "adm0_dif": 1.0, "level": 3.0, "type": "Geo unit", "admin": "United Kingdom", "adm0_a3": "GBR", "geou_dif": 1.0, "geounit": "England", "gu_a3": "ENG", "su_dif": 0.0, "subunit": "England", "su_a3": "ENG", "brk_diff": 0.0, "name": "England", "name_long": "England", "brk_a3": "ENG", "brk_name": "England", "brk_group": null, "abbrev": "Eng.", "postal": "EN", "formal_en": null, "formal_fr": null, "note_adm0": null, "note_brk": null, "name_sort": "England", "name_alt": null, "mapcolor7": 6.0, "mapcolor8": 6.0, "mapcolor9": 6.0, "mapcolor13": 3.0, "pop_est": 53013000.0, "gdp_md_est": 1696816.0, "pop_year": 2011.0, "lastcensus": -99.0, "gdp_year": 2009.0, "economy": "1. Developed region: G7", "income_grp": "1. High income: OECD", "wikipedia": -99.0, "fips_10": null, "iso_a2": "-99", "iso_a3": "-99", "iso_n3": "-99", "un_a3": "-099", "wb_a2": "-99", "wb_a3": "-99", "woe_id": -99.0, "adm0_a3_is": "-99", "adm0_a3_us": "GBR", "adm0_a3_un": -99.0, "adm0_a3_wb": -99.0, "continent": "Europe", "region_un": "Europe", "subregion": "Northern Europe", "region_wb": "Europe & Central Asia", "name_len": 7.0, "long_len": 7.0, "abbrev_len": 4.0, "tiny": -99.0, "homepart": 1.0 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -3.422719467108379, 51.426848167406092 ], [ -3.391281786596835, 51.429795449954099 ], [ -2.668380868488896, 51.614064311432571 ], [ -2.674050679611185, 51.829517134084483 ], [ -3.104956324914895, 52.030795428930162 ], [ -3.067105906132781, 52.768956112129331 ], [ -2.723816560830244, 52.935063859856427 ], [ -3.093830673788716, 53.404547400669685 ], [ -3.092079637047107, 53.404440822963579 ], [ -2.945008510744344, 53.984999701546712 ], [ -3.614700825433033, 54.600936773292574 ], [ -3.229568912844513, 54.935834088586944 ], [ -2.264468454398525, 55.43625654852201 ], [ -2.228723992974551, 55.668595547777443 ], [ -2.005675679673857, 55.804902850350175 ], [ -1.11499101399221, 54.624986477265395 ], [ -0.4304849918542, 54.464376125702188 ], [ 0.184981316742039, 53.325014146531032 ], [ 0.469976840831805, 52.929999498092002 ], [ 1.681530795914682, 52.739520168664001 ], [ 1.559987827164321, 52.099998480836007 ], [ 1.050561557630942, 51.806760565795685 ], [ 1.449865349950244, 51.289427802121907 ], [ 0.550333693045502, 50.765738837275876 ], [ -0.787517462558696, 50.77498891865622 ], [ -2.489997524414434, 50.500018622431242 ], [ -2.956273972984093, 50.696879991247044 ], [ -3.617448085942385, 50.228355617872751 ], [ -4.542507900399244, 50.341837063185665 ], [ -5.245023159191135, 49.959999904981089 ], [ -5.776566941745273, 50.159677639356858 ], [ -4.309989793301895, 51.210001125689189 ], [ -3.414850633142123, 51.42600861266925 ], [ -3.422719467108379, 51.426848167406092 ] ] ] ] } }
]
}

活动

import android.graphics.Color;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMapOptions;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.Polygon;
import com.google.maps.android.geojson.GeoJsonFeature;
import com.google.maps.android.geojson.GeoJsonGeometry;
import com.google.maps.android.geojson.GeoJsonLayer;
import com.google.maps.android.geojson.GeoJsonPolygon;
import com.google.maps.android.geojson.GeoJsonPolygonStyle;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

public class EuroMap extends FragmentActivity implements OnMapReadyCallback {

private GoogleMap mMap;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_euro_map);
    // Obtain the SupportMapFragment and get notified when the map is ready to be used.
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
}

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;

    mMap.setMapType(GoogleMap.MAP_TYPE_NONE);


    LatLngBounds EUROPEBOUNDS = new LatLngBounds(
            new LatLng(34, -15), new LatLng(65, 40));
    LatLngBounds EUROPE_M_BOUNDS = new LatLngBounds(
            new LatLng(45, 0), new LatLng(65, 21));

    mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(EUROPEBOUNDS, 100,100,0));
    mMap.animateCamera(CameraUpdateFactory.zoomTo(4),1000,null);
    mMap.setLatLngBoundsForCameraTarget(EUROPE_M_BOUNDS);


    try{
        final GeoJsonLayer all_rough = new GeoJsonLayer(googleMap, R.raw.england, getApplicationContext());


        final GeoJsonPolygonStyle myPolygonStyle = all_rough.getDefaultPolygonStyle();
        myPolygonStyle.setFillColor(Color.parseColor("#ffffff"));
        myPolygonStyle.setStrokeColor(Color.parseColor("#8a8a8a"));
        myPolygonStyle.setStrokeWidth(2);
        myPolygonStyle.setZIndex(2);

        final GeoJsonPolygonStyle englandStyle = new GeoJsonPolygonStyle();
        englandStyle.setFillColor(Color.parseColor("#FF5733"));
        englandStyle.setStrokeColor(Color.parseColor("#42C0FB"));
        englandStyle.setStrokeWidth(2);
        englandStyle.setZIndex(3);

        all_rough.addLayerToMap();

        all_rough.setOnFeatureClickListener(new GeoJsonLayer.GeoJsonOnFeatureClickListener() {
            @Override
            public void onFeatureClick(GeoJsonFeature feature) {
                Toast.makeText(EuroMap.this,
                        "Feature clicked: " + feature.getProperty("geounit"),
                        Toast.LENGTH_SHORT).show();
            }
        });




    } catch (JSONException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }


}
}

如果您需要更多信息,请与我们联系。任何可以提供的帮助都将非常受欢迎,因为我目前正面临前进的障碍。

我期待任何回复......谢谢!

1 个答案:

答案 0 :(得分:0)

好的,所以我一直在深入研究这个问题,现在我找到了一个有效的解决方案。

不幸的是,它没有提供在MultiPolygon中加载和使用clicklistener的解决方案,因此在此方面有更多的替代解决方案空间。

我的解决方案:

基本上,我使用了GeoJSON文件,并将MultiPolygons分解为多边形(所有个体" split"多边形具有相同的特征"属性")。这允许正确加载几何和属性信息并在程序中单击。为此,我使用了一个名为QGIS(http://www.qgis.org/en/site/)的程序,它是免费的开源和建议:

https://gis.stackexchange.com/questions/64214/saving-of-multipolygon-shape-file-into-a-individual-polygon-shape-files

其中一个缺点是,希腊现在由许多几何体组成,所以如果其中一个被点击,它们就不会一起变化,只有你点击的那些变化。显然应该可以(我希望)用额外的代码来实现这一点。