Densify and Generalize

Loading

Code

/* Copyright 2018 Esri
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package com.esri.arcgisruntime.sample.densifygeneralize;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.CheckBox;
import android.widget.SeekBar;

import com.esri.arcgisruntime.geometry.GeometryEngine;
import com.esri.arcgisruntime.geometry.Multipoint;
import com.esri.arcgisruntime.geometry.Point;
import com.esri.arcgisruntime.geometry.PointCollection;
import com.esri.arcgisruntime.geometry.Polyline;
import com.esri.arcgisruntime.geometry.SpatialReference;
import com.esri.arcgisruntime.mapping.ArcGISMap;
import com.esri.arcgisruntime.mapping.Basemap;
import com.esri.arcgisruntime.mapping.view.Graphic;
import com.esri.arcgisruntime.mapping.view.GraphicsOverlay;
import com.esri.arcgisruntime.mapping.view.MapView;
import com.esri.arcgisruntime.symbology.SimpleLineSymbol;
import com.esri.arcgisruntime.symbology.SimpleMarkerSymbol;

public class MainActivity extends AppCompatActivity {

  private MapView mMapView;
  private SeekBar mMaxSegmentLengthSlider;
  private SeekBar mMaxDeviationSlider;
  private CheckBox mDensifyCheckBox;
  private CheckBox mGeneralizeCheckBox;
  private Graphic mResultPointGraphic;
  private Graphic mResultPolylineGraphic;
  private Polyline mOriginalPolyline;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // inflate MapView from layout
    mMapView = findViewById(R.id.mapView);
    // create a map with a basemap
    ArcGISMap map = new ArcGISMap(Basemap.createStreetsNightVector());
    // set the map to be displayed in this view
    mMapView.setMap(map);

    // inflate views from layout
    mMaxSegmentLengthSlider = findViewById(R.id.maxSegmentLengthBar);
    mMaxDeviationSlider = findViewById(R.id.maxDeviationBar);
    mDensifyCheckBox = findViewById(R.id.densifyCheckBox);
    mGeneralizeCheckBox = findViewById(R.id.generalizeCheckBox);

    // create graphics overlay
    GraphicsOverlay graphicsOverlay = new GraphicsOverlay();
    mMapView.getGraphicsOverlays().add(graphicsOverlay);

    // create some points along a river for the original geometry
    PointCollection points = createShipPoints();

    // show the original points as red dots on the map
    Multipoint originalMultipoint = new Multipoint(points);
    Graphic originalPointsGraphic = new Graphic(originalMultipoint,
        new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CIRCLE, 0xFFFF0000, 7));
    graphicsOverlay.getGraphics().add(originalPointsGraphic);

    // show a dotted red line connecting the original points
    mOriginalPolyline = new Polyline(points);
    Graphic originalPolylineGraphic = new Graphic(mOriginalPolyline, new SimpleLineSymbol(SimpleLineSymbol.Style.DOT,
        0xFFFF0000, 3));
    graphicsOverlay.getGraphics().add(originalPolylineGraphic);

    // show the result (densified and generalized) point as magenta dots on the map
    mResultPointGraphic = new Graphic();
    mResultPointGraphic.setSymbol(new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CIRCLE, 0xFFFF00FF, 7));
    graphicsOverlay.getGraphics().add(mResultPointGraphic);

    // connect the results points with a magenta line
    mResultPolylineGraphic = new Graphic();
    mResultPolylineGraphic.setSymbol(new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, 0xFFFF00FF, 3));
    graphicsOverlay.getGraphics().add(mResultPolylineGraphic);

    mMapView.setViewpointGeometryAsync(mOriginalPolyline.getExtent(), 100);

    // set defaults
    mMaxDeviationSlider.setMax(249);
    mMaxSegmentLengthSlider.setMax(400);
    mGeneralizeCheckBox.setChecked(true);
    mDensifyCheckBox.setChecked(true);
    setListeners();
    updateGeometry();
  }

  /**
   * Adds listeners to both seek bars and both check boxes.
   */
  private void setListeners() {
    mMaxDeviationSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
      @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        updateGeometry();
      }

      @Override public void onStartTrackingTouch(SeekBar seekBar) {
      }

      @Override public void onStopTrackingTouch(SeekBar seekBar) {
      }
    });

    mMaxSegmentLengthSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
      @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        updateGeometry();
      }

      @Override public void onStartTrackingTouch(SeekBar seekBar) {
      }

      @Override public void onStopTrackingTouch(SeekBar seekBar) {
      }
    });

    mGeneralizeCheckBox.setOnClickListener(v -> updateGeometry());
    mDensifyCheckBox.setOnClickListener(v -> updateGeometry());

  }

  /**
   * Called when any of the densify/generalize option values are changed. Applies the densify and generalize
   * operations to the original polyline and updates the result graphics with the result geometry.
   */
  private void updateGeometry() {
    Polyline tempPolyline = mOriginalPolyline;
    if (mGeneralizeCheckBox.isChecked()) {
      tempPolyline = (Polyline) GeometryEngine.generalize(tempPolyline, mMaxDeviationSlider.getProgress() + 1,
          true);
    }
    if (mDensifyCheckBox.isChecked()) {
      tempPolyline = (Polyline) GeometryEngine.densify(tempPolyline, mMaxSegmentLengthSlider.getProgress() + 100);
    }
    mResultPolylineGraphic.setGeometry(tempPolyline);
    Multipoint multipoint = new Multipoint(tempPolyline.getParts().getPartsAsPoints());
    mResultPointGraphic.setGeometry(multipoint);
  }

  /**
   * Creates a collection of points along the Willamette River in Portland, OR.
   *
   * @return points
   */
  private static PointCollection createShipPoints() {
    PointCollection points = new PointCollection(SpatialReference.create(32126));
    points.add(new Point(2330611.130549, 202360.002957, 0.000000));
    points.add(new Point(2330583.834672, 202525.984012, 0.000000));
    points.add(new Point(2330574.164902, 202691.488009, 0.000000));
    points.add(new Point(2330689.292623, 203170.045888, 0.000000));
    points.add(new Point(2330696.773344, 203317.495798, 0.000000));
    points.add(new Point(2330691.419723, 203380.917080, 0.000000));
    points.add(new Point(2330435.065296, 203816.662457, 0.000000));
    points.add(new Point(2330369.500800, 204329.861789, 0.000000));
    points.add(new Point(2330400.929891, 204712.129673, 0.000000));
    points.add(new Point(2330484.300447, 204927.797132, 0.000000));
    points.add(new Point(2330514.469919, 205000.792463, 0.000000));
    points.add(new Point(2330638.099138, 205271.601116, 0.000000));
    points.add(new Point(2330725.315888, 205631.231308, 0.000000));
    points.add(new Point(2330755.640702, 206433.354860, 0.000000));
    points.add(new Point(2330680.644719, 206660.240923, 0.000000));
    points.add(new Point(2330386.957926, 207340.947204, 0.000000));
    points.add(new Point(2330485.861737, 207742.298501, 0.000000));
    return points;
  }

  @Override
  protected void onPause() {
    super.onPause();
    mMapView.pause();
  }

  @Override
  protected void onResume() {
    super.onResume();
    mMapView.resume();
  }

  @Override
  protected void onDestroy() {
    super.onDestroy();
    mMapView.dispose();
  }
}


In this topic
  1. Code