Select to view content in your preferred language

How to get Full Extent of a Shapefile loaded with ArcGISDynamicMapServiceLayer ?

3974
6
Jump to solution
06-25-2013 07:08 AM
JeremieJoalland1
Deactivated User
The ArcGIS Runtime sample "Datasources > Add Shapefile" provide source code to select a shapefile and add it to the map based on a blank MPK (Map Package) and a map service (on the LocalServer).

From that, I would like to be able to get the Full Extent of this layer (from menu "Zoom To Layer").

In my case, I have a World wide blank MPK, so any kind of Shapefile will be loaded. basically, from 2 identical blank MPK, I can load 2 different Shapefile, one with European countries, another with USA countries.
I need to be able to zoom to first Layer on "Europe" or to second layer on "USA" !

But my issue is :
- if I try to get the full extent from the Dynamic Layer, with getFullExtent(), I will get the Envelope from the MPK which is always the World extent.
- How can I get the Full Extent from sub-layers of the dynamic layer to only get the Envelope of my Shapefile (sublayer[0]) ??
0 Kudos
1 Solution

Accepted Solutions
SachinKanaujia
Deactivated User
One approach could be to query the Dynamic layers for the extents and then use that to implement the Zoom to Layer.

         HttpClient client = new DefaultHttpClient();
         HttpPost post = new HttpPost(MapServiceUrl + "/dynamicLayer?");
         List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
         nameValuePairs.add(new BasicNameValuePair("layer", queryParam));

         post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
         HttpResponse response = client.execute(post);
         BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));

Where queryParam can be formed from dynamics layers
String queryParam= "{\"id\":0,\"source\":{\"type\":\"dataLayer\",\"dataSource\":{\"type\":\"" + type + "\",\"workspaceId\":\"" + workspaceId + "\",\"dataSourceName\":\"" + layerName + "\"}}}";

You can put type = "table" for Feature Layers, Workspaceid can be obtained from the added dynamic layer and layername in the name of the shapefile or layer that was added.

You can then parse this using the Json parser and get the required extents or any other info that is required

JsonNode extentNode = parseJson(rd).findValue("extent");
extentNode.findValue("xmin").asDouble();
extentNode.findValue("ymin").asDouble();
extentNode.findValue("xmax").asDouble();
extentNode.findValue("ymax").asDouble();

Here is the method for parsing JSON

private static JsonNode parseJson(BufferedReader jsonStr) {
   JsonFactory jfactory = new JsonFactory();
   JsonNode rootNode = null;
   try {
    ObjectMapper mapper = new ObjectMapper(jfactory);
    rootNode = mapper.readTree(jsonStr);
   } catch (JsonParseException e2) {
    e2.printStackTrace();
   } catch (Exception e2) {
    e2.printStackTrace();
   }
   return rootNode;
    }

I hope this helps !!!!



The ArcGIS Runtime sample "Datasources > Add Shapefile" provide source code to select a shapefile and add it to the map based on a blank MPK (Map Package) and a map service (on the LocalServer).

From that, I would like to be able to get the Full Extent of this layer (from menu "Zoom To Layer").

In my case, I have a World wide blank MPK, so any kind of Shapefile will be loaded. basically, from 2 identical blank MPK, I can load 2 different Shapefile, one with European countries, another with USA countries.
I need to be able to zoom to first Layer on "Europe" or to second layer on "USA" !

But my issue is :
- if I try to get the full extent from the Dynamic Layer, with getFullExtent(), I will get the Envelope from the MPK which is always the World extent.
- How can I get the Full Extent from sub-layers of the dynamic layer to only get the Envelope of my Shapefile (sublayer[0]) ??

View solution in original post

0 Kudos
6 Replies
SachinKanaujia
Deactivated User
One approach could be to query the Dynamic layers for the extents and then use that to implement the Zoom to Layer.

         HttpClient client = new DefaultHttpClient();
         HttpPost post = new HttpPost(MapServiceUrl + "/dynamicLayer?");
         List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
         nameValuePairs.add(new BasicNameValuePair("layer", queryParam));

         post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
         HttpResponse response = client.execute(post);
         BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));

Where queryParam can be formed from dynamics layers
String queryParam= "{\"id\":0,\"source\":{\"type\":\"dataLayer\",\"dataSource\":{\"type\":\"" + type + "\",\"workspaceId\":\"" + workspaceId + "\",\"dataSourceName\":\"" + layerName + "\"}}}";

You can put type = "table" for Feature Layers, Workspaceid can be obtained from the added dynamic layer and layername in the name of the shapefile or layer that was added.

You can then parse this using the Json parser and get the required extents or any other info that is required

JsonNode extentNode = parseJson(rd).findValue("extent");
extentNode.findValue("xmin").asDouble();
extentNode.findValue("ymin").asDouble();
extentNode.findValue("xmax").asDouble();
extentNode.findValue("ymax").asDouble();

Here is the method for parsing JSON

private static JsonNode parseJson(BufferedReader jsonStr) {
   JsonFactory jfactory = new JsonFactory();
   JsonNode rootNode = null;
   try {
    ObjectMapper mapper = new ObjectMapper(jfactory);
    rootNode = mapper.readTree(jsonStr);
   } catch (JsonParseException e2) {
    e2.printStackTrace();
   } catch (Exception e2) {
    e2.printStackTrace();
   }
   return rootNode;
    }

I hope this helps !!!!



The ArcGIS Runtime sample "Datasources > Add Shapefile" provide source code to select a shapefile and add it to the map based on a blank MPK (Map Package) and a map service (on the LocalServer).

From that, I would like to be able to get the Full Extent of this layer (from menu "Zoom To Layer").

In my case, I have a World wide blank MPK, so any kind of Shapefile will be loaded. basically, from 2 identical blank MPK, I can load 2 different Shapefile, one with European countries, another with USA countries.
I need to be able to zoom to first Layer on "Europe" or to second layer on "USA" !

But my issue is :
- if I try to get the full extent from the Dynamic Layer, with getFullExtent(), I will get the Envelope from the MPK which is always the World extent.
- How can I get the Full Extent from sub-layers of the dynamic layer to only get the Envelope of my Shapefile (sublayer[0]) ??
0 Kudos
JeremieJoalland1
Deactivated User
thanks Sachin, it's working fine ! 😉

Actually, I already had part of the solution because I'm getting the Geometry Type of shapefiles the same way, but I'm still new to http request and JSon.

here's my code :
private Envelope requestHttpExtent(final DynamicLayerInfo layerInfo, final String urlMapService) {
 Envelope envelope = null;

 try {
  String layerParam = layerInfo.toJson();

  HttpClient client = new DefaultHttpClient();
  HttpPost post = new HttpPost(urlMapService + "/dynamicLayer?");
  List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
  nameValuePairs.add(new BasicNameValuePair("layer", layerParam));
  post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
  HttpResponse response = client.execute(post);
  BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));

  JsonNode extentNode = parseJson(rd).findValue("extent");
  if (extentNode != null) {
   double xMin = extentNode.findValue("xmin").asDouble();
   double yMin = extentNode.findValue("ymin").asDouble();
   double xMax = extentNode.findValue("xmax").asDouble();
   double yMax = extentNode.findValue("ymax").asDouble();

   envelope = new Envelope(xMin, yMin, xMax, yMax);
  }

 } catch (Exception e) {
  // do nothing
  envelope = null;
 }

 return envelope;
}
0 Kudos
SachinKanaujia
Deactivated User
Glad that you got it working.

I agree. Its based on the REST API calls. It a matter to getting the request parameters formed correctly


-Sachin

thanks Sachin, it's working fine ! 😉

Actually, I already had part of the solution because I'm getting the Geometry Type of shapefiles the same way, but I'm still new to http request and JSon.

here's my code :
private Envelope requestHttpExtent(final DynamicLayerInfo layerInfo, final String urlMapService) {
 Envelope envelope = null;

 try {
  String layerParam = layerInfo.toJson();

  HttpClient client = new DefaultHttpClient();
  HttpPost post = new HttpPost(urlMapService + "/dynamicLayer?");
  List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
  nameValuePairs.add(new BasicNameValuePair("layer", layerParam));
  post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
  HttpResponse response = client.execute(post);
  BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));

  JsonNode extentNode = parseJson(rd).findValue("extent");
  if (extentNode != null) {
   double xMin = extentNode.findValue("xmin").asDouble();
   double yMin = extentNode.findValue("ymin").asDouble();
   double xMax = extentNode.findValue("xmax").asDouble();
   double yMax = extentNode.findValue("ymax").asDouble();

   envelope = new Envelope(xMin, yMin, xMax, yMax);
  }

 } catch (Exception e) {
  // do nothing
  envelope = null;
 }

 return envelope;
}
0 Kudos
GuangyuWu
New Contributor
Thanks for all the information. I was able to get the full extent using this method. However, the results from the REST API query do not have the geometries (features) included. I tried to set "returnGeometry" as "true",

nameValuePairs.add(new BasicNameValuePair("returnGeometry", "true"));

but still not working.

I used StringBuilder to get the content from the BufferedReader rd

StringBuilder builder = new StringBuilder();
                  for (String line = null; (line = rd.readLine()) != null;) {
                      builder.append(line).append("\n");
                  }

The builder output has all the spatial reference information and fields, but no features.

Can anyone let me know how to set the parameters correctly in this case? Any help will be greatly appreciated. Thanks.

Guangyu
0 Kudos
JeremieJoalland1
Deactivated User
... However, the results from the REST API query do not have the geometries (features) included. I tried to set "returnGeometry" as "true",

nameValuePairs.add(new BasicNameValuePair("returnGeometry", "true"));

but still not working.

I used StringBuilder to get the content from the BufferedReader rd

StringBuilder builder = new StringBuilder();
                  for (String line = null; (line = rd.readLine()) != null;) {
                      builder.append(line).append("\n");
                  }

The builder output has all the spatial reference information and fields, but no features.

Can anyone let me know how to set the parameters correctly in this case?


This previous issue should provide you the answer :
Thread: How to get Geometry Type for a Shapefile loaded as ArcGISDynamicMapServiceLayer ?
0 Kudos
GuangyuWu
New Contributor
Thanks for your information. But we wanted is the geometries with coordinates (features), not just Geometry Type.

I have figured out that we can add "query" in the HTTP request to get features out

HttpPost post = new HttpPost(localMapService.getUrlMapService() + "/dynamicLayer/query?"


I tested with a LocalMapService, it works.
0 Kudos