arcgissamples\mapbean\TrackGPS.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.mapbean; import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.IOException; import java.net.UnknownHostException; import java.util.Random; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.Timer; import javax.swing.UIManager; import com.esri.arcgis.beans.map.MapBean; import com.esri.arcgis.carto.FeatureLayer; import com.esri.arcgis.carto.IElement; import com.esri.arcgis.carto.IGraphicsContainer; import com.esri.arcgis.carto.ILayer; import com.esri.arcgis.carto.MarkerElement; import com.esri.arcgis.carto.SimpleRenderer; import com.esri.arcgis.carto.esriViewDrawPhase; import com.esri.arcgis.controls.IMapControlEvents2Adapter; import com.esri.arcgis.controls.IMapControlEvents2OnMouseDownEvent; import com.esri.arcgis.display.CharacterMarkerSymbol; import com.esri.arcgis.display.IRgbColor; import com.esri.arcgis.display.RgbColor; import com.esri.arcgis.display.SimpleFillSymbol; import com.esri.arcgis.display.SimpleLineSymbol; import com.esri.arcgis.geometry.IGeographicCoordinateSystem; import com.esri.arcgis.geometry.IProjectedCoordinateSystem; import com.esri.arcgis.geometry.Point; import com.esri.arcgis.geometry.Polygon; import com.esri.arcgis.geometry.SpatialReferenceEnvironment; import com.esri.arcgis.geometry.esriSRGeoCSType; import com.esri.arcgis.geometry.esriSRProjCSType; import com.esri.arcgis.interop.AutomationException; import com.esri.arcgis.support.ms.stdole.StdFont; import com.esri.arcgis.system.AoInitialize; import com.esri.arcgis.system.EngineInitializer; import com.esri.arcgis.system.esriLicenseProductCode; import com.esri.arcgis.system.esriLicenseStatus; /** * Description:This sample demonstrates adding elements to a Map's GraphicsContainer, and then moving them in response * to a timer. It also demonstrates setting a coordinatate systems and projecting data. */ public class TrackGPS extends JFrame implements ActionListener { /** * */ private static final long serialVersionUID = 1L; JPanel mainPanel = null; JPanel bottomPanel = null; IGeographicCoordinateSystem geographicCoordinateSystem = null; IProjectedCoordinateSystem projectedCoordinateSystem = null; IGraphicsContainer graphicsContainer = null; MapBean mapBean; AgentInField agentArray[]; String helpString = "<HTML> Use the left mouse button to zoom in. Use the other mouse buttons to <BR> click on an agent and change the symbology. </HTML>"; JLabel helpLabel = null; JButton zoomFullExtentButton = null; JCheckBox gpsTrackingCheck = null; Timer timer = null; public TrackGPS(){ super("Geo Events"); buildFrame(); setSize(800, 500); setVisible(true); initControl(); } /** * Initializes control and member variables. */ public void initControl() { //Get the developer kit home location String devKitHome = System.getenv("AGSDEVKITJAVA"); String filePath = devKitHome + File.separator + "java" + File.separator + "samples" + File.separator + "data" + File.separator + "world"; try { // Add sample shapefile data mapBean.addShapeFile(filePath, "world30"); mapBean.addShapeFile(filePath, "continent"); mapBean.addIMapControlEvents2Listener(new MapControlListener()); // Symbolize the data symbolizeData(mapBean.getLayer(0), 0.1, getRGBColor(0, 0, 0), getRGBColor(0, 128, 0)); symbolizeData(mapBean.getLayer(1), 0.1, getRGBColor(0, 0, 0), getRGBColor(140, 196, 254)); // mapBean.refresh(esriViewDrawPhase.esriViewBackground, null, null); // Set up a global Geographic Coordinate System makeCoordinateSystem(); // Get the MapBean's graphics container and get the IGraphicsContainer interface // mapBean.refresh(esriViewDrawPhase.esriViewBackground, null, null); graphicsContainer = mapBean.getActiveView().getGraphicsContainer(); agentArray = new AgentInField[20]; // Populate an array with agent id's and locations loadAgentArray(); // Loop through the array and display each agent location for (int i = 0; i < agentArray.length - 1; i++) createContainerElements(agentArray[i]); mapBean.refresh(esriViewDrawPhase.esriViewBackground, null, null); // Create timer object timer = new Timer(1000, new TimerListener()); timer.stop(); } catch (IOException ex) { System.out.println("Exception in initConrol #" + ex); ex.printStackTrace(); } } public void buildFrame(){ mainPanel = new JPanel(); bottomPanel = new JPanel(); mainPanel.setLayout(new BorderLayout()); bottomPanel.setLayout(new FlowLayout(FlowLayout.LEFT)); gpsTrackingCheck = new JCheckBox("Enable GPS Tracking"); gpsTrackingCheck.addActionListener(this); helpLabel = new JLabel(helpString); zoomFullExtentButton = new JButton("Zoom to Full Extent"); zoomFullExtentButton.addActionListener(this); bottomPanel.add(gpsTrackingCheck); bottomPanel.add(helpLabel); bottomPanel.add(zoomFullExtentButton); // Create map control add it to the center of the main panel. mapBean = new MapBean(); mainPanel.add(mapBean, BorderLayout.CENTER); mainPanel.add(bottomPanel, BorderLayout.SOUTH); mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); getContentPane().add(mainPanel, BorderLayout.CENTER); } /** * @see java.awt.event.ActionListener#actionPerformed(ActionEvent event) * @param event */ public void actionPerformed(ActionEvent event) { if (event.getSource() == gpsTrackingCheck) { if (gpsTrackingCheck.isSelected()) { timer.start(); } else { if (timer.isRunning()) { timer.stop(); } } } if (event.getSource() == zoomFullExtentButton) { try { // Assign map controls extent property to the full extent of all the layers mapBean.setExtent(mapBean.getFullExtent()); } catch (Exception ex) { System.out.println("Exception in zoomFullExtentButton action performed : " + ex); ex.printStackTrace(); } } } /** * Uses agent data to create a point object. The point object is then projected onto projected coordinates on the * map control and added to graphic container. * * @param agent */ public void createContainerElements(AgentInField agent) { try { Point point = new Point(); point.putCoords(agent.Longitude, agent.Latitude); // Set the points spatial reference - WHERE the point is coming FROM point.setSpatialReferenceByRef(geographicCoordinateSystem); // Project the point onto the display's current spatial reference - WHERE the point is going TO point.project(projectedCoordinateSystem); // Create a marker element MarkerElement element = new MarkerElement(); // Set the elements geometry element.setGeometry(point); element.setSymbol(getMarkerSymbol(agent.Located)); // set the agent located to element properties if (agent.Located) { element.setName("True"); } else { element.setName("False"); } // Add the element to the graphics containe graphicsContainer.addElement(element, 0); } catch (IOException ex) { System.out.println("Exception in displayAgentLocation : " + ex); ex.printStackTrace(); } } /** * Creates a symbol based on the agent location. */ public CharacterMarkerSymbol getMarkerSymbol(boolean located) { try { // Create a new font StdFont font = new StdFont(); font.setName("ESRI Crime Analysis"); font.setBold(true); // Create a new CharacterMarkerSymbol CharacterMarkerSymbol characterMarkerSymbol = new CharacterMarkerSymbol(); characterMarkerSymbol.setFont(font); // Set the marker symbol properties if (located) { characterMarkerSymbol.setCharacterIndex(56); characterMarkerSymbol.setColor(getRGBColor(255, 0, 0)); characterMarkerSymbol.setSize(30); } else { characterMarkerSymbol.setCharacterIndex(46); characterMarkerSymbol.setColor(getRGBColor(0, 0, 0)); characterMarkerSymbol.setSize(30); } return characterMarkerSymbol; } catch (IOException ex) { ex.printStackTrace(); return null; } } /** * Creates array of latitude and longitude values. */ public void loadAgentArray() { // Populate an array of agent locations and id's. // The locations are in decimal degrees, // based on the WGS1984 geographic coordinate system. (ie unprojected). // Obviously, these values could be read directly from a GPS unit. for (int i = 0; i < agentArray.length; i++) { agentArray[i] = new AgentInField(); } agentArray[0].CodeNumber = "001"; agentArray[0].Latitude = 56.185128983308; agentArray[0].Longitude = 37.556904400607; agentArray[0].Located = false; agentArray[1].CodeNumber = "002"; agentArray[1].Latitude = 48.3732928679818; agentArray[1].Longitude = 6.91047040971168; agentArray[1].Located = false; agentArray[2].CodeNumber = "003"; agentArray[2].Latitude = 32.1487101669196; agentArray[2].Longitude = 39.3596358118361; agentArray[2].Located = false; agentArray[3].CodeNumber = "004"; agentArray[3].Latitude = 29.7450682852807; agentArray[3].Longitude = 71.2078907435508; agentArray[3].Located = false; agentArray[4].CodeNumber = "005"; agentArray[4].Latitude = 38.7587253414264; agentArray[4].Longitude = 138.509863429439; agentArray[4].Located = false; agentArray[5].CodeNumber = "006"; agentArray[5].Latitude = 35.1532625189681; agentArray[5].Longitude = -82.0242792109256; agentArray[5].Located = false; agentArray[6].CodeNumber = "007"; agentArray[6].Latitude = -26.1396054628225; agentArray[6].Longitude = 28.5432473444613; agentArray[6].Located = true; agentArray[7].CodeNumber = "008"; agentArray[7].Latitude = 33.9514415781487; agentArray[7].Longitude = 3.90591805766313; agentArray[7].Located = false; agentArray[8].CodeNumber = "009"; agentArray[8].Latitude = 29.7450682852807; agentArray[8].Longitude = 16.5250379362671; agentArray[8].Located = false; agentArray[9].CodeNumber = "010"; agentArray[9].Latitude = 45.9696509863429; agentArray[9].Longitude = 23.1350531107739; agentArray[9].Located = false; agentArray[10].CodeNumber = "011"; agentArray[10].Latitude = 48.9742033383915; agentArray[10].Longitude = 14.1213960546282; agentArray[10].Located = false; agentArray[11].CodeNumber = "012"; agentArray[11].Latitude = 29.7450682852807; agentArray[11].Longitude = 79.0197268588771; agentArray[11].Located = false; agentArray[12].CodeNumber = "013"; agentArray[12].Latitude = 43.5660091047041; agentArray[12].Longitude = 125.289833080425; agentArray[12].Located = false; agentArray[13].CodeNumber = "014"; agentArray[13].Latitude = 7.5113808801214; agentArray[13].Longitude = -68.2033383915023; agentArray[13].Located = false; agentArray[14].CodeNumber = "015"; agentArray[14].Latitude = 9.31411229135053; agentArray[14].Longitude = -79.6206373292868; agentArray[14].Located = false; agentArray[15].CodeNumber = "016"; agentArray[15].Latitude = 8.71320182094082; agentArray[15].Longitude = -9.31411229135053; agentArray[15].Located = true; agentArray[16].CodeNumber = "017"; agentArray[16].Latitude = 22.5341426403642; agentArray[16].Longitude = 53.7814871016692; agentArray[16].Located = false; agentArray[17].CodeNumber = "018"; agentArray[17].Latitude = 42.3641881638847; agentArray[17].Longitude = 45.9696509863429; agentArray[17].Located = false; agentArray[18].CodeNumber = "019"; agentArray[18].Latitude = 39.3596358118361; agentArray[18].Longitude = 27.9423368740516; agentArray[18].Located = false; agentArray[19].CodeNumber = "020"; agentArray[19].Latitude = 22.5341426403642; agentArray[19].Longitude = 104.257966616085; agentArray[19].Located = false; } /** * Adds symbology to map */ private void symbolizeData(ILayer layer, double width, IRgbColor colorLine, IRgbColor colorFill) { try { // Create a simple line symbol SimpleLineSymbol simpleLineSymbol = new SimpleLineSymbol(); simpleLineSymbol.setWidth(width); simpleLineSymbol.setColor(colorLine); // Create a fill symbol SimpleFillSymbol fillSymbol = new SimpleFillSymbol(); // Set the fill symbol properties fillSymbol.setOutline(simpleLineSymbol); fillSymbol.setColor(colorFill); // Create a simple renderer SimpleRenderer simpleRenderer = new SimpleRenderer(); // Set the simple renderer properties simpleRenderer.setSymbolByRef(fillSymbol); // Create Featurelayer using layer Object FeatureLayer featureLayer = (FeatureLayer) layer; // Set featurelayer properties featureLayer.setRendererByRef(simpleRenderer); } catch (IOException ex) { System.out.println("Exception in symbolizeData : " + ex); ex.printStackTrace(); } } /** * Sets the spatial reference property of the map control to projected coordinate system. */ public void makeCoordinateSystem() { try { // Create a spatial reference environment SpatialReferenceEnvironment spatialReferenceEnvironment = new SpatialReferenceEnvironment(); // Create a geographic coordinate system and get the IGeographicCoordinateSystem interface geographicCoordinateSystem = spatialReferenceEnvironment .createGeographicCoordinateSystem(esriSRGeoCSType.esriSRGeoCS_WGS1984); // Create a projected coordinate system projectedCoordinateSystem = spatialReferenceEnvironment .createProjectedCoordinateSystem(esriSRProjCSType.esriSRProjCS_World_Mollweide); // Set the map controls spatial reference property mapBean.setSpatialReferenceByRef(projectedCoordinateSystem); } catch (IOException ex) { System.out.println("Exception in makeCoordinateSystem : " + ex); ex.printStackTrace(); } } /** * creates an rgb color object * * @param red * @param green * @param blue * @return RgbColor */ private RgbColor getRGBColor(int red, int green, int blue) { RgbColor rgbColor = null; try { // Create rgb color and grab hold of the IRGBColor interface rgbColor = new RgbColor(); rgbColor.setRed(red); rgbColor.setGreen(green); rgbColor.setBlue(blue); rgbColor.setUseWindowsDithering(true); } catch (Exception ex) { System.out.println("Error in getRGBFunction :" + ex); ex.printStackTrace(); } return rgbColor; } /** * Class which is to hold agent information */ class AgentInField { public double Latitude; public double Longitude; public String CodeNumber; public boolean Located; } /** * Class which extends map control event class IMapControlEvents2Adapter * * @see com.esri.arcgis.beans.map.IMapControlEvents2Adapter */ class MapControlListener extends IMapControlEvents2Adapter { private static final long serialVersionUID = 1L; /** * @see com.esri.arcgis.beans.map.IMapControlEvents2Adapter#onMouseDown(IMapControlEvents2OnMouseDownEvent * theEvent) * @param theEvent */ public void onMouseDown(IMapControlEvents2OnMouseDownEvent theEvent) { try { // If left mouse button then zoom in if (theEvent.getButton() == 1) { mapBean.setExtent(mapBean.trackRectangle()); } else { // Create a point Point point = new Point(); point.putCoords(theEvent.getMapX(), theEvent.getMapY()); // Create a polygon by buffering the point Polygon polygon = (Polygon) point.buffer(mapBean.getExtent().getWidth() * 0.02); // Draw the polygon mapBean.drawShape(polygon, null); // Loop through the elements in the GraphicContainer and get the IElement interface graphicsContainer.reset(); IElement element = graphicsContainer.next(); while (element != null) { // If the polygon contains the point if (polygon.contains(element.getGeometry())) { // Create a marker symbol using IElement inteface MarkerElement markerElement = (MarkerElement) element; markerElement.setSymbol(getMarkerSymbol(true)); // Get Elmentproperties and set the value to true markerElement.setName("True"); } element = graphicsContainer.next(); } if (!gpsTrackingCheck.isSelected()) { // Refresh the graphics mapBean.refresh(esriViewDrawPhase.esriViewGraphics, null, null); } } } catch (Exception ex) { System.out.println("Exception in MapControlListener#onMouseDown : " + ex); ex.printStackTrace(); } } }// End of MapControlListener class /** * Timer listener which extends from ActionListner. Used to randomly assign new x and y coordinates to each point * within the GraphicsContainer after a specified time interval */ class TimerListener implements ActionListener { public void actionPerformed(ActionEvent event) { Random random = new Random(); // // Loop through the elements in the GraphicContainer and move them a little, // but keep them within the limits of the projection. // try { graphicsContainer.reset(); IElement element = null; for (element = graphicsContainer.next(); element != null; element = graphicsContainer.next()) { MarkerElement markerElement = (MarkerElement) element; if (markerElement.getName().equalsIgnoreCase("True")) { continue; } moveElement(element, random); } mapBean.refresh(esriViewDrawPhase.esriViewGraphics, null, null); } catch (IOException e) { e.printStackTrace(); } } void moveElement(IElement element, Random random) throws UnknownHostException, IOException { double maxLatChange = 10.0; double maxLngChange = 20.0; double x = 0, y = 0; Point point = new Point(); point = (Point) element.getGeometry(); point.project(geographicCoordinateSystem); // // An AutomationException can be thrown when calling getX or getY on // a point that has been "invalidated" by doing a projection on it when // it had bad coordinates. This happens when the latitute is beyond or // very near the poles. If this happens, we just reset the point to 0,0. // In the longitude direction, this doesn't happen as often because // these wrap around. That is, you can set a value greater than 180 or // less than -180 and the point doesn't get invalidated upon projection. // There is a limit, however. // try { x = point.getX() - (maxLngChange * (random.nextDouble() - 0.5)); y = point.getY() - (maxLatChange * (random.nextDouble() - 0.5)); } catch (AutomationException e) { // The point was invalidated, so x & y are 0 } point.setX(x); point.setY(y); point.project(projectedCoordinateSystem); element.setGeometry(point); } } public static void main(String s[]){ try{ EngineInitializer.initializeVisualBeans(); // Set the system look and feel UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); initializeArcGISLicenses(); TrackGPS geoEvents = new TrackGPS(); geoEvents.setDefaultCloseOperation(TrackGPS.EXIT_ON_CLOSE); }catch (Exception ex){ ex.printStackTrace(); } } static void initializeArcGISLicenses() { try { AoInitialize ao = new AoInitialize(); if (ao.isProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeEngine) == esriLicenseStatus.esriLicenseAvailable) ao.initialize(esriLicenseProductCode.esriLicenseProductCodeEngine); else if (ao.isProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeArcView) == esriLicenseStatus.esriLicenseAvailable) ao.initialize(esriLicenseProductCode.esriLicenseProductCodeArcView); } catch (Exception e) {e.printStackTrace();} } }