package com.nutiteq.advancedmap3; import android.os.Bundle; import com.nutiteq.core.MapPos; import com.nutiteq.core.MapRange; import com.nutiteq.datasources.LocalVectorDataSource; import com.nutiteq.geometry.GeoJSONGeometryReader; import com.nutiteq.geometry.Geometry; import com.nutiteq.layers.ClusterElementBuilder; import com.nutiteq.layers.ClusteredVectorLayer; import com.nutiteq.layers.VectorLayer; import com.nutiteq.styles.BalloonPopupStyle; import com.nutiteq.styles.BalloonPopupStyleBuilder; import com.nutiteq.vectorelements.BalloonPopup; import com.nutiteq.vectorelements.VectorElement; import com.nutiteq.wrappedcommons.VectorElementVector; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; import java.io.InputStream; import java.util.Iterator; /** * A sample demonstrating how to read data from GeoJSON and add clustered Markers to map. * Both points from GeoJSON, and cluster markers are shown as Ballons which have dynamic texts * * NB! Suggestions if you have a lot of points (tens or hundreds of thousands) and clusters: * 1. Use Point geometry instead of Balloon or Marker * 2. Instead of Balloon with text generate dynamically Point bitmap with cluster numbers * 3. Make sure you reuse cluster style bitmaps. Creating new bitmap in rendering has technical cost */ public class ClusteredGeoJsonActivity extends VectorMapSampleBaseActivity { static class MyClusterElementBuilder extends ClusterElementBuilder { BalloonPopupStyle balloonPopupStyle; public MyClusterElementBuilder(){ balloonPopupStyle = new BalloonPopupStyleBuilder().buildStyle(); } @Override public VectorElement buildClusterElement(MapPos pos, VectorElementVector elements) { // Cluster popup has just a number of cluster elements, and default style // You can create here also Marker, Point etc. Point is suggested for big number of objects // Note: pos has center of the cluster coordinates BalloonPopup popup = new BalloonPopup( pos, balloonPopupStyle, Long.toString(elements.size()), ""); return popup; } } @Override protected void onCreate(Bundle savedInstanceState) { // MapSampleBaseActivity creates and configures mapView super.onCreate(savedInstanceState); // 1. Initialize a local vector data source LocalVectorDataSource vectorDataSource1 = new LocalVectorDataSource(baseProjection); // Initialize a vector layer with the previous data source VectorLayer vectorLayer1 = new ClusteredVectorLayer(vectorDataSource1, new MyClusterElementBuilder()); // Add the previous vector layer to the map mapView.getLayers().add(vectorLayer1); // Set visible zoom range for the vector layer vectorLayer1.setVisibleZoomRange(new MapRange(0, 18)); // read GeoJSON // parse it as normal JSON, then use SDK parser for GeoJSON geometries try { String jsonStr = loadJSONFromAsset(); JSONObject json = new JSONObject(jsonStr); GeoJSONGeometryReader geoJsonParser = new GeoJSONGeometryReader(); BalloonPopupStyle balloonPopupStyle = new BalloonPopupStyleBuilder().buildStyle(); JSONArray features = json.getJSONArray("features"); for (int i = 0; i < features.length(); i++) { JSONObject feature = (JSONObject) features.get(i); JSONObject geometry = feature.getJSONObject("geometry"); // use SDK GeoJSON parser Geometry ntGeom = geoJsonParser.readGeometry(geometry.toString()); JSONObject properties = feature.getJSONObject("properties"); // create popup for each object BalloonPopup popup = new BalloonPopup( ntGeom, balloonPopupStyle, properties.getString("Capital"), properties.getString("Country")); // add all properties as MetaData, so you can use it with click handling for (Iterator<String> j = properties.keys(); j.hasNext();){ String key = j.next(); String val = properties.getString(key); popup.setMetaDataElement(key,val); } vectorDataSource1.add(popup); } } catch (JSONException e) { e.printStackTrace(); } } public String loadJSONFromAsset() { String json = null; try { InputStream is = getAssets().open("capitals_3857.geojson"); int size = is.available(); byte[] buffer = new byte[size]; is.read(buffer); is.close(); json = new String(buffer, "UTF-8"); } catch (IOException ex) { ex.printStackTrace(); return null; } return json; } }