GeoJSON onClickListener не работает над многоугольниками

71
6

ОБНОВИТЬ:

Оригинальный вопрос ниже строки, но я рассмотрел это дополнительно и добавлю дополнительную информацию.

Во-первых, причина возникновения ошибки заключается в том, что файл GeoJSON содержит многоугольники, которые классифицируются как "MultiPolygons". Они представляют собой несколько многоугольников, определенных вместе. (представьте, что вы пытаетесь представить такую страну, как Греция, как единое целое в файле, сама страна состоит из многих островов и, следовательно, требует "MultiPolygons")

Я попробовал код ниже с файлом GeoJSON, который я сделал с помощью простого многоугольника, определенного как "Многоугольник" (не "Multipolygon"), и код работает так, как должен.

Теперь вопрос становится... есть способ использовать метод onclick для MultiPolygons, и если да, то как это будет реализовано.

Я буду продолжать тестировать и публиковать здесь, если мне повезет, иначе любой вклад будет оценен.

Я изучал добавление файла geoJSON в карты google и взаимодействие с ним в приложении Android.

У Google есть утилита для работы с картами, чтобы помочь в этом:

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

Мне удалось успешно импортировать информацию geojson (в данном случае MultiPolygons со свойствами) и может извлекать свойства свойств и т.д. Из java-программы.

Следующим шагом, который я хотел сделать, было иметь возможность щелкнуть Polygon и извлечь одну и ту же информацию о свойствах или добавить новый полигональ к нажатой "функции".

Я нашел код в 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")

код будет работать, и по щелчку вы получите тост с "Feature clicked:"

Вот ошибка:

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, а свойство (в данном случае) - "Англия". Я проверил это, используя следующий код, и он работает (код изменяет цвет многоугольника и выводит "Сообщение: Англия" в журнале):

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();
}

}
}

Если вам нужна дополнительная информация, дайте мне знать. Любая помощь, которая может быть предоставлена, будет очень признательна, поскольку я в настоящее время против стены с точки зрения продвижения вперед.

Я с нетерпением жду любых отзывов... и спасибо!

спросил(а) 2016-09-11T14:44:00+03:00 4 года, 2 месяца назад
1
Решение
102

ОК, поэтому я смотрел дальше, и теперь у меня есть решение, которое работает.

К сожалению, он не обеспечивает решение для загрузки в MultiPolygon и с помощью кликмена, поэтому для этого есть больше возможностей для альтернативных решений.

Мое решение:

В принципе, я взял файл GeoJSON, который у меня был, и разделил MultiPolygons на Polygons (все отдельные "расщепленные" полигоны имеют одинаковые свойства "свойства"). Это позволяет правильно загрузить геометрию и информацию о свойствах и щелкнуть в программе. Для этого я использовал программу QGIS (http://www.qgis.org/en/site/), которая является бесплатной и открытой версией, и предложения здесь:

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

Один из недостатков заключается в том, что Греция, например, теперь состоит из многих геометрий, поэтому, если кто-то из них щелкнул, они не все меняются вместе, а только тот, который вы нажали. Очевидно, что это должно быть возможно (я надеюсь), чтобы это произошло с дополнительным кодом.

ответил(а) 2016-09-11T17:41:00+03:00 4 года, 2 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема