Select to view content in your preferred language

How to get Geometry Type for a Shapefile loaded as ArcGISDynamicMapServiceLayer ?

4575
3
Jump to solution
04-09-2013 04:08 AM
JeremieJoalland1
Occasional Contributor II
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).

My question is how can I get the shapefile Geometry Type before adding it as ArcGISDynamicMapServiceLayer, in order to define the correct Symbol type to pass on DrawingInfo ?

source code from ArcGIS sample:
/**
 * Set up shapefile workspace
 */
private void addShapefile(final String fileName, final String fileDir) {
    final String workspaceId = ""+count++; // an arbitrary unique string

    // create a local map service and enable dynamic layers
    LocalMapService localMapService = new LocalMapService(URL_BLANK_MPK);
    localMapService.setEnableDynamicLayers(true);
    
    // get dynamic workspaces from service
    WorkspaceInfoSet workspaceInfoSet = localMapService.getDynamicWorkspaces();
    
    // create a workspace info via the static method according to data type
    // e.g. shapefile folder connection
    WorkspaceInfo workspaceInfo = WorkspaceInfo.CreateShapefileFolderConnection(workspaceId, fileDir);

    // set dynamic workspaces for our local map service
    workspaceInfoSet.add(workspaceInfo);
    localMapService.setDynamicWorkspaces(workspaceInfoSet);

    // now start service...
    localMapService.start();

    // set up a local dynamic layer
    final ArcGISDynamicMapServiceLayer localDynamicLayer = 
        new ArcGISDynamicMapServiceLayer(localMapService.getUrlMapService());

    // add the layer to the map
    map.getLayers().add(localDynamicLayer);

    localDynamicLayer.addLayerInitializeCompleteListener(new LayerInitializeCompleteListener()
    {
        @Override
        public void layerInitializeComplete(LayerInitializeCompleteEvent arg0)
        {
            DynamicLayerInfoCollection layerInfos = localDynamicLayer.getDynamicLayerInfos();
            DynamicLayerInfo layerInfo = layerInfos.get(0);

            // Apply a renderer for vector layers.
            // QUESTION : HOW CAN WE DETERMINE THE GEOMETRY TYPE BEFORE, 
            //   IN ORDER TO DEFINE THE RIGHT SYMBOL HERE ?? 
            DrawingInfo drawingInfo = new DrawingInfo(simpleRenderer, TRANSPARENCY);
            layerInfo.setDrawingInfo(drawingInfo);

            // Create the data source
            TableDataSource dataSource = new TableDataSource();
            dataSource.setWorkspaceId(workspaceId);
            dataSource.setDataSourceName(fileName);
            
            // Set the data source
            LayerDataSource layerDataSource = new LayerDataSource();
            layerDataSource.setDataSource(dataSource);
            layerInfo.setLayerSource(layerDataSource);
            
            localDynamicLayer.refresh();
        }
    });
}


even after adding it, I don't know how to do it as GeometryType seems to be available only on GraphicsLayer/ArcGISFeatureLayer.
It would be great to be able to do something like this with DynamicLayer/ArcGISDynamicMapServiceLayer :

private Symbol getSymbolForGeometryType(GraphicsLayer layer) {

    // Here: If I replace parameter by "DynamicLayer layer", then getNumberOfGraphics() is not available !
         as dynamic layers doesn't manage Graphics...
    
    Symbol symbol = new SimpleMarkerSymbol(Color.BLACK, 10, Style.SQUARE);
 
    Geometry geometry = null;
    if(layer.getNumberOfGraphics() > 0) {
        int id = layer.getGraphicIDs()[0];
        geometry = layer.getGraphic(id).getGeometry();
    }
    
    if(geometry != null){
        switch(geometry.getType()){
        case POINT:
        case MULTIPOINT:
         symbol = new SimpleMarkerSymbol(Color.ORANGE, 10, Style.CIRCLE);
            break;
        case LINE:
        case POLYLINE:
         symbol = new SimpleLineSymbol(Color.RED, 2.0f);
            break;
        case POLYGON:
            Color polyFillColor = new Color(0, 255, 255, 125);
            symbol = new SimpleFillSymbol(polyFillColor, new SimpleLineSymbol(Color.ORANGE, 2.0f));
            break;
          case ENVELOPE:
            break;
          case UNKNOWN:
            break;
          default:
            break;
        }
    }
    
    return symbol;
}
0 Kudos
1 Solution

Accepted Solutions
EliseAcheson1
Occasional Contributor
Hi,

The API doesn't have something specific for this case at the moment but we hope to better support this workflow at the upcoming release.

At the moment, you can get the geometry type of the layer by creating a request yourself as described on this page:

http://resources.arcgis.com/en/help/rest/apiref/dynamicLayer.html

From the sample code snippet you quote, you can rearrange the order a bit and use the LayerDataSource to create your request parameters...

        DynamicLayerInfoCollection layerInfos = localDynamicLayer.getDynamicLayerInfos();         DynamicLayerInfo layerInfo = layerInfos.get(0);          // Create the data source         TableDataSource dataSource = new TableDataSource();         dataSource.setWorkspaceId(workspaceId);         dataSource.setDataSourceName(fileName);          // Set the data source         LayerDataSource layerDataSource = new LayerDataSource();         layerDataSource.setDataSource(dataSource);         layerInfo.setLayerSource(layerDataSource);          // NEW STUFF HERE             LayerInfo li = new LayerInfo(0, layerDataSource);         String layerParam = null;         String geometryType = null;         try {           layerParam = li.toJson();                      // make an http request, e.g. this code adapted from http://www.vogella.com/articles/ApacheHttpClient/article.html           HttpClient client = new DefaultHttpClient();           HttpPost post = new HttpPost(localMapService.getUrlMapService() + "/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()));           String line = "";           while ((line = rd.readLine()) != null) {             // can get the geometry type from the response line, for example...             String regexp = "esriGeometry(\\w+)";             Pattern pattern = Pattern.compile(regexp);             Matcher matcher = pattern.matcher(line);             matcher.find();             geometryType = matcher.group().replaceAll(regexp, "$1");             System.out.println(geometryType);           }          } catch (Exception e) {           e.printStackTrace();         }         // END NEW STUFF              // create renderer based on geometry, etc.          DrawingInfo drawingInfo = new DrawingInfo(myRenderer, myTransparency);         layerInfo.setDrawingInfo(drawingInfo);          localDynamicLayer.refresh();


The regexp stuff in particular is proof of concept... better to properly parse the Json that gets returned...

Hope that helps,

~elise

View solution in original post

0 Kudos
3 Replies
EliseAcheson1
Occasional Contributor
Hi,

The API doesn't have something specific for this case at the moment but we hope to better support this workflow at the upcoming release.

At the moment, you can get the geometry type of the layer by creating a request yourself as described on this page:

http://resources.arcgis.com/en/help/rest/apiref/dynamicLayer.html

From the sample code snippet you quote, you can rearrange the order a bit and use the LayerDataSource to create your request parameters...

        DynamicLayerInfoCollection layerInfos = localDynamicLayer.getDynamicLayerInfos();         DynamicLayerInfo layerInfo = layerInfos.get(0);          // Create the data source         TableDataSource dataSource = new TableDataSource();         dataSource.setWorkspaceId(workspaceId);         dataSource.setDataSourceName(fileName);          // Set the data source         LayerDataSource layerDataSource = new LayerDataSource();         layerDataSource.setDataSource(dataSource);         layerInfo.setLayerSource(layerDataSource);          // NEW STUFF HERE             LayerInfo li = new LayerInfo(0, layerDataSource);         String layerParam = null;         String geometryType = null;         try {           layerParam = li.toJson();                      // make an http request, e.g. this code adapted from http://www.vogella.com/articles/ApacheHttpClient/article.html           HttpClient client = new DefaultHttpClient();           HttpPost post = new HttpPost(localMapService.getUrlMapService() + "/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()));           String line = "";           while ((line = rd.readLine()) != null) {             // can get the geometry type from the response line, for example...             String regexp = "esriGeometry(\\w+)";             Pattern pattern = Pattern.compile(regexp);             Matcher matcher = pattern.matcher(line);             matcher.find();             geometryType = matcher.group().replaceAll(regexp, "$1");             System.out.println(geometryType);           }          } catch (Exception e) {           e.printStackTrace();         }         // END NEW STUFF              // create renderer based on geometry, etc.          DrawingInfo drawingInfo = new DrawingInfo(myRenderer, myTransparency);         layerInfo.setDrawingInfo(drawingInfo);          localDynamicLayer.refresh();


The regexp stuff in particular is proof of concept... better to properly parse the Json that gets returned...

Hope that helps,

~elise
0 Kudos
JeremieJoalland1
Occasional Contributor II
Thanks a lot. your solution is working fine and will do it for now...

regarding the upcoming release for ArcGIS Runtime for Java, do you have an estimated date ??
0 Kudos
EricBader
Regular Contributor II
We are planning for the 10.2 release to be in late July 2013.
0 Kudos