arcgissamples\geoprocessing\CalculateLineOfSight.java
/* Copyright 2010 ESRI * * All rights reserved under the copyright laws of the United States * and applicable international laws, treaties, and conventions. * * You may freely redistribute and use this sample code, with or * without modification, provided you include the original copyright * notice and use restrictions. * * See the use restrictions. * */ package arcgissamples.geoprocessing; import java.io.File; import com.esri.arcgis.datasourcesfile.ShapefileWorkspaceFactory; import com.esri.arcgis.datasourcesraster.RasterDataset; import com.esri.arcgis.datasourcesraster.RasterWorkspace; import com.esri.arcgis.datasourcesraster.RasterWorkspaceFactory; import com.esri.arcgis.geodatabase.IFeature; import com.esri.arcgis.geodatabase.IFeatureClass; import com.esri.arcgis.geodatabase.IGPMessages; import com.esri.arcgis.geodatabase.IWorkspace; import com.esri.arcgis.geodatabase.Workspace; import com.esri.arcgis.geometry.ISpatialReference; import com.esri.arcgis.geometry.Point; import com.esri.arcgis.geometry.Polyline; import com.esri.arcgis.geoprocessing.GeoProcessor; import com.esri.arcgis.geoprocessing.tools.analyst3dtools.LineOfSight; import com.esri.arcgis.geoprocessing.tools.datamanagementtools.AddField; import com.esri.arcgis.geoprocessing.tools.datamanagementtools.CreateFeatureclass; import com.esri.arcgis.system.AoInitialize; import com.esri.arcgis.system.EngineInitializer; import com.esri.arcgis.system.esriLicenseExtensionCode; import com.esri.arcgis.system.esriLicenseProductCode; import com.esri.arcgis.system.esriLicenseStatus; /** * This class demonstrates the use of Line Of Sight (LOS) Geoprocessing tool. It assumes you points for the observer and * target and it calculates whether the two points are visible. It also calculates the visibility of surface features * along the path between the two points. The line defining the two points can either be 2D or 3D (Z-Aware). A 3D line * assumes the target and observer are at a height above sea level equal to the Z value. If it is 2D then the LOS tool * assumes that the target and observer are on the surface with an offset of 1 for the observer. By setting values for * the offsetA and offsetB fields the target and observer can be raised off the surface or above their z value. */ public class CalculateLineOfSight { GeoProcessor gp = null; public CalculateLineOfSight() { // create the geoprocessor and allow it to overwrite output try { gp = new GeoProcessor(); gp.setOverwriteOutput(true); } catch (Exception e) { e.printStackTrace(); } } /** * Calculates line of sight * @param demFolder * @param demName * @param outputFolder * @return */ private boolean lineOfSight(String demFolder, String demName, String outputFolder) { final double startX = 476265.710; final double startY = 224771.386; // the z values will be used for the 3D dataset final double startZ = 3091.00; // this offset is for the 2D dataset and represent the difference between the height of the DEM and // startZ at the start point final double startOffset = 100.0; final double endX = 488347.964; final double endY = 213629.843; final double endZ = 3140.00; final double endOffset = 100.00; String Line2DName = File.separator + "2dLine.shp"; String Line3DName = File.separator + "3dLine.shp"; // open the DEM to get it's spatial reference and to pass into the line of sight ISpatialReference demSR = null; RasterDataset rdataset = null; try { RasterWorkspaceFactory rwf = new RasterWorkspaceFactory(); IWorkspace workspace = rwf.openFromFile(demFolder, 0); RasterWorkspace rworkspace = new RasterWorkspace(workspace); rdataset = (RasterDataset) rworkspace.openRasterDataset(demName); demSR = rdataset.getSpatialReference(); } catch (Exception e) { e.printStackTrace(); return false; } // create the new feature class containing the points to be used for calculating line of sight try { // This sample creates a 2d and a 3d polyline feature class for the line of sight of interest. The // geoprocessing // tool for line of sight handles 2d and 3d polylines differently in terms of assumed heights for targets. // Please // see the documentation for the Line of Sight tool for a further explanation CreateFeatureclass cfc = new CreateFeatureclass(outputFolder, Line2DName); cfc.setGeometryType("polyline"); cfc.setSpatialReference(demSR); gp.execute(cfc, null); System.out.println("Made the 2D polyline"); cfc.setOutName(Line3DName); cfc.setHasZ("enabled"); gp.execute(cfc, null); System.out.println("Created the 3d polyline"); } catch (Exception e) { // iterate through the GP messages to see what went wrong try { IGPMessages gpMessages = gp.getReturnMessages(); for (int i = 0; i < gpMessages.getCount(); i++) { System.out.println(gpMessages.getMessage(i).getDescription()); } } catch (Exception e2) { } e.printStackTrace(); return false; } // add the offsetA and offsetB fields for the 2d line try { AddField addField = new AddField(outputFolder + Line2DName, "OffsetA", "double"); gp.execute(addField, null); addField.setFieldName("OffsetB"); gp.execute(addField, null); } catch (Exception e) { e.printStackTrace(); try { IGPMessages gpMessages = gp.getReturnMessages(); for (int i = 0; i < gpMessages.getCount(); i++) { System.out.println(gpMessages.getMessage(i).getDescription()); } } catch (Exception e2) { } return false; } // add the points - there is no way to do this though GP so we have to use lower level arcobjects try { ShapefileWorkspaceFactory swf = new ShapefileWorkspaceFactory(); Workspace sfworkspace = (Workspace) swf.openFromFile(outputFolder, 0); IFeatureClass fc2d = sfworkspace.openFeatureClass(Line2DName.substring(0, Line2DName.lastIndexOf('.'))); Point startPoint = new Point(); startPoint.setX(startX); startPoint.setY(startY); Point endPoint = new Point(); endPoint.setX(endX); endPoint.setY(endY); Polyline polyline2d = new Polyline(); polyline2d.setFromPoint(startPoint); polyline2d.setToPoint(endPoint); // this method for adding a feature is easier but does not give the ability to undo. Use a cursor and // edit operations to have undo capabilities IFeature feature = fc2d.createFeature(); int a_id = feature.getFields().findField("OffsetA"); int b_id = feature.getFields().findField("OffsetB"); feature.setShapeByRef(polyline2d); feature.setValue(a_id, new Double(startOffset)); feature.setValue(b_id, new Double(endOffset)); feature.store(); // now edit the 3d dataset IFeatureClass fc3d = sfworkspace.openFeatureClass(Line3DName.substring(0, Line3DName.lastIndexOf('.'))); Point startPoint3d = new Point(); startPoint3d.setZAware(true); startPoint3d.setX(startX); startPoint3d.setY(startY); startPoint3d.setZ(startZ); Point endPoint3d = new Point(); endPoint3d.setZAware(true); endPoint3d.setX(endX); endPoint3d.setY(endY); endPoint3d.setZ(endZ); Polyline polyline3d = new Polyline(); polyline3d.setZAware(true); polyline3d.setFromPoint(startPoint3d); polyline3d.setToPoint(endPoint3d); IFeature feature3d = fc3d.createFeature(); feature3d.setShapeByRef(polyline3d); feature3d.store(); } catch (Exception e) { e.printStackTrace(); return false; } // call line of sight try { LineOfSight los = new LineOfSight(demFolder + File.separator + demName, outputFolder + Line2DName, outputFolder + File.separator + "result2d.shp"); gp.execute(los, null); System.out.println("Created the 2D results"); los.setInLineFeatureClass(outputFolder + Line3DName); los.setOutLosFeatureClass(outputFolder + File.separator + "result3d.shp"); gp.execute(los, null); System.out.println("Created the 3D results"); } catch (Exception e) { e.printStackTrace(); try { IGPMessages gpMessages = gp.getReturnMessages(); for (int i = 0; i < gpMessages.getCount(); i++) { System.out.println(gpMessages.getMessage(i).getDescription()); } } catch (Exception e2) { } return false; } return true; } public static void main(String[] args) { System.out.println("Line of Sight - An ArcObjects Java SDK Developer Sample"); try { // Initialize the engine and licenses. EngineInitializer.initializeEngine(); AoInitialize aoInit = new AoInitialize(); initializeArcGISLicenses(aoInit); //Get DEVKITHOME Home String devKitHome = System.getenv("AGSDEVKITJAVA"); // Change the following lines if you want to use different data but you will also have to change the coordinates // for the points String inDEM = devKitHome + "java" + File.separator + "samples" + File.separator + "data" + File.separator + "raster"; String inDEMName = "dem1"; String outShapePath = getOutputDir() + File.separator + "lineOfSight"; File outShapefileDir = new File(outShapePath); outShapefileDir.mkdir(); CalculateLineOfSight los = new CalculateLineOfSight(); if (los.lineOfSight(inDEM, inDEMName, outShapePath)) { System.out.println("Everything worked - please go look in " + outShapePath); } else { System.out.println("Something went wrong please consult error messages"); } } catch(Exception e) { e.printStackTrace(); } } /** * Initializes the lowest available ArcGIS License */ private static void initializeArcGISLicenses(AoInitialize aoInit) { try { if (aoInit.isProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeEngine) == esriLicenseStatus.esriLicenseAvailable) { aoInit.initialize(esriLicenseProductCode.esriLicenseProductCodeEngine); } else if (aoInit.isProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeArcView) == esriLicenseStatus.esriLicenseAvailable) { aoInit.initialize(esriLicenseProductCode.esriLicenseProductCodeArcView); } else { System.err.println("Could not initialize an Engine or ArcView license. Exiting application."); System.exit(-1); } aoInit.checkOutExtension(esriLicenseExtensionCode.esriLicenseExtensionCode3DAnalyst); } catch (Exception e) { e.printStackTrace(); } } /** * Retrieve output directory * @return */ private static String getOutputDir() { String userDir; if (System.getProperty("os.name").toLowerCase().indexOf("win") > -1) userDir = System.getenv("UserProfile"); else userDir = System.getenv("HOME"); String outputDir = userDir + File.separator + "arcgis_sample_output"; System.out.println("Creating output directory - " + outputDir); new File(outputDir).mkdir(); return outputDir; } }