I want to know a simple and easy way to parse KML file and store its data in an object so that I can access its data instantly here is my kml file
You can use KmlContainer from Google Maps KML Importing Utility to access any property in a container:
...
KmlLayer layer = new KmlLayer(getMap(), kmlInputStream, getApplicationContext());
Iterable containers = layer.getContainers();
for (KmlContainer container : containers ) {
if (container.hasProperty("property_name")) {
// process property
Log.d(TAG, "" + container.getProperty("property_name"));
}
}
...
For exactly yours kml file for standard geometry you can use something like this:
#Override
public void onMapReady(GoogleMap googleMap) {
mGoogleMap = googleMap;
mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(17.425868, 78.459761), 16));
// change next line for your kml source
InputStream kmlInputStream = getResources().openRawResource(R.raw.data);
try {
KmlLayer kmlLayer = new KmlLayer(mGoogleMap, kmlInputStream, getApplicationContext());
kmlLayer.addLayerToMap();
ArrayList<LatLng> pathPoints = new ArrayList();
if (kmlLayer != null && kmlLayer.getContainers() != null) {
for (KmlContainer container : kmlLayer.getContainers()) {
if (container.hasPlacemarks()) {
for (KmlPlacemark placemark : container.getPlacemarks()) {
Geometry geometry = placemark.getGeometry();
if (geometry.getGeometryType().equals("Point")) {
KmlPoint point = (KmlPoint) placemark.getGeometry();
LatLng latLng = new LatLng(point.getGeometryObject().latitude, point.getGeometryObject().longitude);
pathPoints.add(latLng);
} else if (geometry.getGeometryType().equals("LineString")) {
KmlLineString kmlLineString = (KmlLineString) geometry;
ArrayList<LatLng> coords = kmlLineString.getGeometryObject();
for (LatLng latLng : coords) {
pathPoints.add(latLng);
}
}
}
}
}
for (LatLng latLng : pathPoints) {
mGoogleMap.addMarker(new MarkerOptions().position(latLng));
}
}
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
and get something like that:
but for <ExtendedData> you should use external library with KML parsing support like GeoTools or parse your KML file as XML.
Related
i am working with google maps on android studio, in which i draw polygon on map. till this everything going great but now i wanted to store this polygon to sqlite database and then retrieve this data to listView. now i don't understand how to implement this in my code. if anyone have any idea about this then please save me.
here is my code where i draw polygon:
#Override
public void onMapReady(final GoogleMap googleMap) {
final List<LatLng> latLngList = new ArrayList<>(); // list of polygons
final List<Marker> markerList = new ArrayList<>();
mMap = googleMap;
LatLng center = new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude());
final MarkerOptions markerOptions = new MarkerOptions().position(center).title(center.latitude + ":" + center.longitude);
mMap.clear();
googleMap.animateCamera(CameraUpdateFactory.newLatLng(center));
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(center, 18));
googleMap.addMarker(markerOptions);
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(final LatLng latLng) {
int height = 50;
int width = 30;
BitmapDrawable bitmapdraw = (BitmapDrawable)getResources().getDrawable(R.mipmap.marker);
Bitmap b = bitmapdraw.getBitmap();
Bitmap smallMarker = Bitmap.createScaledBitmap(b, width, height, false);
/*Marker marker = googleMap.addMarker(markerOptions);*/
Marker marker = mMap.addMarker(new MarkerOptions().position(latLng).draggable(true).icon(BitmapDescriptorFactory.fromBitmap(smallMarker)));
markerList.add(marker);
latLngList.add(latLng);
drawPolygon(latLngList);
polygon.setClickable(true);
}
});
mMap.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
#Override
public void onMapLongClick(LatLng latLng) {
polygon.remove();
/*marker.remove();
markerList.remove(marker);*/
}
});
}
private void drawPolygon(List<LatLng> latLngList) {
if (polygon != null) {
polygon.remove();
}
PolygonOptions polygonOptions = new PolygonOptions();
polygonOptions.fillColor(0x7F228B22);
polygonOptions.strokeColor(Color.GREEN);
polygonOptions.strokeWidth(5);
polygonOptions.addAll(latLngList);
polygon = mMap.addPolygon(polygonOptions);
}
my listview will look like [![this][1]][1]
You could save principal attributes you want. For example... in my case I needed to save coordinates LatLng and camera zoom. Then you can make a custom class like this.
class CustomLatLng : Serializable{
var latitudeList : MutableList<String> = mutableListOf()
var longitudeList : MutableList<String> = mutableListOf()
var cameraPositionLat : Double = 0.0
var cameraPositionLng : Double = 0.0
var zoomCamera : Float = 12f
fun add(latitude : Double, longitude : Double ){
latitudeList.add(latitude.toString())
longitudeList.add(longitude.toString())
}
fun clearLatLng(){
latitudeList.clear()
longitudeList.clear()
}
fun isNotEmpty(): Boolean{
return !(latitudeList.isEmpty() || longitudeList.isEmpty())
}
}
// in other place of your code put this...
const val PARA_NAME_POLYGONS = "polygons"
fun savePolygon(poligons:CustomLatLng ) {
val editor = sharedPreferences.edit()
editor.putString(PARA_NAME_POLYGONS, serializePolygon(poligons))
editor.apply()
//editor.commit()
}
fun cleanPolygon() {
val editor = sharedPreferences.edit()
editor.remove(PARA_NAME_POLYGONS)
editor.apply()
}
private fun serializePolygon(polygon: CustomLatLng): String {
val gson = Gson()
return gson.toJson(polygon)
}
fun getPolygon():CustomLatLng {
val gson = Gson()
val json = sharedPreferences.getString(PARA_NAME_POLYGONS,"").toString()
if (json.isEmpty())
return CustomLatLng()
return gson.fromJson(json,CustomLatLng::class.java)
}
wherever you have a polygon , save only data that you will need to recreate a Polygon
val customLatLng = CustomLatLng()
polygon?.points?.forEach {
customLatLng.add(it.latitude, it.longitude)
}
customLatLng.zoomCamera = 10f
savePolygon(customLatLng)
note I'm saving only data I need, You must create as many variables as you need, I hope it helps
Good afternoon every one, I manage my google maps v2 with cluster manager(I'm using this library android-maps-utils) and I want to get the diffrence when a marker clicked and when a cluster manager clicked, But methodes doesn't called, So what going wrong in my code, I spent 10 days in this small problem, So Please Help.
HERE IT IS MY WHOLE CODE:
public class BigClusteringDemoActivity extends BaseDemoActivity implements ClusterManager.OnClusterClickListener,ClusterManager.OnClusterItemClickListener {
private ClusterManager<MyItem> mClusterManager;
#Override
protected void startDemo() {
getMap().moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(51.503186, -0.126446), 10));
mClusterManager = new ClusterManager<MyItem>(this, getMap());
getMap().setOnCameraChangeListener(mClusterManager);
try {
readItems();
} catch (JSONException e) {
Toast.makeText(this, "Problem reading list of markers.", Toast.LENGTH_LONG).show();
}
getMap().setOnMarkerClickListener(mClusterManager);
}
private void readItems() throws JSONException {
InputStream inputStream = getResources().openRawResource(R.raw.radar_search);
List<MyItem> items = new MyItemReader().read(inputStream);
for (int i = 0; i < 10; i++) {
double offset = i / 60d;
for (MyItem item : items) {
LatLng position = item.getPosition();
double lat = position.latitude + offset;
double lng = position.longitude + offset;
MyItem offsetItem = new MyItem(lat, lng);
mClusterManager.addItem(offsetItem);
}
}
}
#Override
public boolean onClusterClick(Cluster cluster) {
Log.d("cluster","clicked" + cluster.getItems());
return false;
}
#Override
public boolean onClusterItemClick(ClusterItem item) {
Log.d("cluster","clicked" + item.getPosition());
return false;
}
}
You have not connected your ClusterManager to the map with onClick
You have this one getMap().setOnCameraIdleListener(mClusterManager);
try adding these aswell
getMap().setOnMarkerClickListener(mClusterManager);
mClusterManager.setOnClusterClickListener(this);
mClusterManager.setOnClusterItemClickListener(this);`
This will use the implements for listeners you added.
I have managed to find sequence of ClusterManager initialization for click listeners finally work:
1) init maps
mMap = googleMap
2) init ClusterManager
mClusterManager = ClusterManager(requireContext(), mMap)
3) set Map OnMarkerClickListener
mMap.setOnMarkerClickListener(mClusterManager)
4) init ClusterManager
mClusterManager = ClusterManager(requireContext(), mMap)
5) set cluster click listeners
mClusterManager.setOnClusterItemClickListener {
println("CLUST ITEM CLICK")
return#setOnClusterItemClickListener false
}
mClusterManager.setOnClusterClickListener {
println("CLUST CLICK")
return#setOnClusterClickListener false
}
6) when you use your custom render init it now:
mClusterManager.renderer = CustomIconRenderer(requireContext(), mMap, mClusterManager)
But i can not select each of them separately.
How can I select each of them separately by touching their marker and get their details. A in this function below a json array is used of 0-19(20) elements.
I dont know how to use them to select each marker separately.
private void parseLocationResult(final JSONObject result) {
String id, place_id, placeName = null, reference, icon, vicinity = null;
JSONArray rev;
double latitude;
double longitude;
try {
final JSONArray jsonArray = result.getJSONArray(RESULTS);//JavaScript Object Notation
if (result.getString(STATUS).equalsIgnoreCase(OK)) {
mMap.clear();
for (int i = 0; i < jsonArray.length(); i++) {
final JSONObject place = jsonArray.getJSONObject(i);
id = place.getString(SUPERMARKET_ID);
place_id = place.getString(PLACE_ID);
if (!place.isNull(NAME)) {
placeName = place.getString(NAME);
}
if (!place.isNull(VICINITY)) {
vicinity = place.getString(VICINITY);
}
latitude = place.getJSONObject(GEOMETRY).getJSONObject(LOCATION)
.getDouble(LATITUDE);
longitude = place.getJSONObject(GEOMETRY).getJSONObject(LOCATION)
.getDouble(LONGITUDE);
reference = place.getString(REFERENCE);
icon = place.getString(ICON);
MarkerOptions markerOptions = new MarkerOptions();
final LatLng latLng = new LatLng(latitude, longitude);
markerOptions
.icon(BitmapDescriptorFactory.fromResource(R.drawable.bluemarker))
.position(latLng);
markerOptions.title(placeName + " : " + vicinity);
mMap.addMarker(markerOptions);
}
Toast.makeText(getBaseContext(), jsonArray.length() + " found!",
Toast.LENGTH_LONG).show();
} else if (result.getString(STATUS).equalsIgnoreCase(ZERO_RESULTS)) {
Toast.makeText(getBaseContext(), "Not found in 5KM radius!!!",
Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
e.printStackTrace();
Log.e(TAG, "parseLocationResult: Error=" + e.getMessage());
}
}
implement GoogleMap.OnMarkerClickListener and Override onMarkerClick to detect click on marker
#Override
public boolean onMarkerClick(Marker marker) {
// on marker clicked
if (marker.equals(this.marker)) {
// on specific marker clicked
}
return false;
}
i'm trying to get the coordinates of my kml layer in my android app, and i just cant seem to find how to do it.
i have this kml layer:
KmlLayer layer = new KmlLayer(mMap, R.raw.allowedarea, getApplicationContext());
and i'm trying to get the Latitude and Longtitude list of his boundries points.
ArrayList<LatLnt> latlitArray = layer.soemthing();
could find anything, please guys help.
Try this solution
try {
KmlLayer layer = new KmlLayer(googleMap, R.raw.zone, this);
layer.addLayerToMap();
Iterable<KmlContainer> containers = layer.getContainers();
accessContainers(containers);
} catch (XmlPullParserException | IOException e) {
e.printStackTrace();
}
public void accessContainers(Iterable<KmlContainer> containers) {
for (KmlContainer container : containers) {
if (container != null) {
if (container.hasContainers()) {
accessContainers(container.getContainers());
} else {
if (container.hasPlacemarks()) {
accessPlacemarks(container.getPlacemarks());
}
}
}
}
}
public void accessPlacemarks(Iterable<KmlPlacemark> placemarks) {
for (KmlPlacemark placemark : placemarks) {
if (placemark != null) {
KmlGeometry geometry = placemark.getGeometry();
if (geometry instanceof KmlPolygon) {
KmlPolygon polygon = (KmlPolygon) geometry;
mLatLngList.addAll(polygon.getOuterBoundaryCoordinates());
}
}
}
}
This will recursively access every placemark geometry inside the container. I'm not aware if the object obtained can actually be an instance of any other class or collection besides List and LatLng.
public void accessContainers(Iterable<KmlContainer> containers) {
for(KmlContainer c : containers) {
if(c.hasPlacemarks()) {
for(KmlPlacemark p : c.getPlacemarks()) {
KmlGeometry g = p.getGeometry();
Object object = g.getGeometryObject();
if(object instanceof LatLng) {
LatLng latlng = (LatLng)object;
//Do more stuff with the point
}
if(object instanceof List<?>) {
List<LatLng> list = (List<LatLng>)object;
//Do more stuff with the list of points
}
Log.d(TAG, g.getGeometryType() + ":" + object.toString());
}
}
if(c.hasContainers()) {
accessContainers(c.getContainers());
}
}
}
i created an application that retrieved data from mysql databse. the problem is that the map does not show any marker .
i am using volley library
public class MainActivity extends FragmentActivity {
private GoogleMap mMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setUpMapIfNeeded();
String uri = "localhost/get_all_products.php";
RequestQueue mRequestQueue = Volley.newRequestQueue(getApplicationContext());
JsonArrayRequest request = new JsonArrayRequest(
uri,
new Response.Listener<JSONArray>(){
LatLng location;
#Override
public void onResponse(JSONArray response) {
int count = response.length();
for(int i = 0; i < count; i++){
try {
JSONObject jo = response.getJSONObject(i);
Double lat = Double.parseDouble(jo.getString("lat"));
Double lng = Double.parseDouble(jo.getString("lng"));
location = new LatLng(lat,lng);
MarkerOptions options = new MarkerOptions();
options.position(location);
options.title(jo.getString("product"));
options.snippet(jo.getString("product"));
mMap.addMarker(options);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
CameraUpdate cu = CameraUpdateFactory.newLatLng(location);
mMap.moveCamera(cu);
Toast.makeText(getApplicationContext(), response.toString(), Toast.LENGTH_LONG).show();
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), "onErrorResponse", Toast.LENGTH_LONG).show();
}
}
);
Object TAG_REQUEST_QUEUE = new Object();
request.setTag(TAG_REQUEST_QUEUE);
mRequestQueue.add(request);
mRequestQueue.start();
}
#Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
if (mMap == null) {
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
if (mMap != null) {
}
}
}
}
the map is rteurn without any markers and the application does not crash.
the php files are correct so there is no need to put the code here
thank you :)
--------EDIT
the volley error i get is
org.json.JSONException: value <html><body><script of type java.lang.String cannot be converted to JSONArray
the problem is not in the java or php files.
the host "byethost14.com" is not giving a valid json format for security purposes i guess.
i changed the url to 10.0.2.2 and uploaded my files in xamppserver and it's working
-------advice------
do not use byethost if you want to output json