private void calculateVector() { /* * Notice that this tool assumes that each record in the shapefile is an * individual polygon. The feature can contain multiple parts only if it * has holes, i.e. islands. A multipart record cannot contain multiple * and seperate features. This is because it complicates the calculation * of feature area and perimeter. */ amIActive = true; // Declare the variable. String inputFile = null; int progress; double featureArea = 0; double circleArea = 0; double radius = 0; int recNum; int j, i; double[][] vertices = null; CoordinateArraySequence coordArray; LinearRing ring; MinimumBoundingCircle mbc; GeometryFactory factory = new GeometryFactory(); Geometry geom; if (args.length <= 0) { showFeedback("Plugin parameters have not been set."); return; } inputFile = args[0]; /* * args[1], args[2], and args[3] are ignored by the vector tool */ // check to see that the inputHeader and outputHeader are not null. if (inputFile == null) { showFeedback("One or more of the input parameters have not been set properly."); return; } try { ShapeFile input = new ShapeFile(inputFile); double numberOfRecords = input.getNumberOfRecords(); if (input.getShapeType().getBaseType() != ShapeType.POLYGON) { showFeedback("This function can only be applied to polygon type shapefiles."); return; } /* create a new field in the input file's database to hold the fractal dimension. Put it at the end of the database. */ DBFField field = new DBFField(); field = new DBFField(); field.setName("RC_CIRCLE"); field.setDataType(DBFField.DBFDataType.NUMERIC); field.setFieldLength(10); field.setDecimalCount(4); input.getAttributeTable().addField(field); // initialize the shapefile. ShapeType inputType = input.getShapeType(); for (ShapeFileRecord record : input.records) { switch (inputType) { case POLYGON: whitebox.geospatialfiles.shapefile.Polygon recPolygon = (whitebox.geospatialfiles.shapefile.Polygon) (record.getGeometry()); vertices = recPolygon.getPoints(); coordArray = new CoordinateArraySequence(vertices.length); j = 0; for (i = 0; i < vertices.length; i++) { coordArray.setOrdinate(j, 0, vertices[i][0]); coordArray.setOrdinate(j, 1, vertices[i][1]); j++; } geom = factory.createMultiPoint(coordArray); mbc = new MinimumBoundingCircle(geom); radius = mbc.getRadius(); circleArea = Math.PI * radius * radius; featureArea = recPolygon.getArea(); break; case POLYGONZ: PolygonZ recPolygonZ = (PolygonZ) (record.getGeometry()); vertices = recPolygonZ.getPoints(); coordArray = new CoordinateArraySequence(vertices.length); j = 0; for (i = 0; i < vertices.length; i++) { coordArray.setOrdinate(j, 0, vertices[i][0]); coordArray.setOrdinate(j, 1, vertices[i][1]); j++; } geom = factory.createMultiPoint(coordArray); mbc = new MinimumBoundingCircle(geom); radius = mbc.getRadius(); circleArea = Math.PI * radius * radius; featureArea = recPolygonZ.getArea(); break; case POLYGONM: PolygonM recPolygonM = (PolygonM) (record.getGeometry()); vertices = recPolygonM.getPoints(); coordArray = new CoordinateArraySequence(vertices.length); j = 0; for (i = 0; i < vertices.length; i++) { coordArray.setOrdinate(j, 0, vertices[i][0]); coordArray.setOrdinate(j, 1, vertices[i][1]); j++; } geom = factory.createMultiPoint(coordArray); mbc = new MinimumBoundingCircle(geom); radius = mbc.getRadius(); circleArea = Math.PI * radius * radius; featureArea = recPolygonM.getArea(); break; } recNum = record.getRecordNumber() - 1; Object[] recData = input.getAttributeTable().getRecord(recNum); if (circleArea > 0) { recData[recData.length - 1] = new Double(1 - featureArea / circleArea); } else { recData[recData.length - 1] = new Double(0); } input.getAttributeTable().updateRecord(recNum, recData); if (cancelOp) { cancelOperation(); return; } progress = (int) (record.getRecordNumber() / numberOfRecords * 100); updateProgress(progress); } // returning the database file will result in it being opened in the Whitebox GUI. returnData(input.getDatabaseFile()); } catch (OutOfMemoryError oe) { myHost.showFeedback("An out-of-memory error has occurred during operation."); } catch (Exception e) { myHost.showFeedback("An error has occurred during operation. See log file for details."); myHost.logException("Error in " + getDescriptiveName(), e); } finally { updateProgress("Progress: ", 0); // tells the main application that this process is completed. amIActive = false; myHost.pluginComplete(); } }
/** * Create device locations in a path near the main zone. * * @param assignment * @param start * @return * @throws SiteWhereException */ protected List<IDeviceLocation> createDeviceLocations(IDeviceAssignment assignment, Date date) throws SiteWhereException { long current = date.getTime(); Polygon zone = GeoUtils.createPolygonForLocations(zoneLocations); Point centroid = zone.getCentroid(); // Calculate length of steps between locations based on bounding circle. MinimumBoundingCircle circle = new MinimumBoundingCircle(zone); double step = circle.getRadius() / 10; double cx = centroid.getX(); double cy = centroid.getY(); double deltaX = (Math.sqrt(Math.random()) * step * 2) - step; double deltaY = (Math.sqrt(Math.random()) * step * 2) - step; // Used to rotate deltas to turn path and stay inside polygon. AffineTransformation xform = new AffineTransformation(); xform.rotate(Math.toRadians(22.5)); List<IDeviceLocation> results = new ArrayList<IDeviceLocation>(); GeometryFactory factory = new GeometryFactory(); for (int x = 0; x < LOCATIONS_PER_ASSIGNMENT; x++) { boolean foundNext = false; // Add a little randomness to path. double waver = ((Math.random() * 20) - 10.0); AffineTransformation waverXform = new AffineTransformation(); waverXform.rotate(Math.toRadians(waver)); Coordinate waverDelta = new Coordinate(deltaX, deltaY); waverXform.transform(waverDelta, waverDelta); deltaX = waverDelta.x; deltaY = waverDelta.y; while (!foundNext) { Coordinate start = new Coordinate(cx, cy); Coordinate end = new Coordinate(cx + deltaX, cy + deltaY); Coordinate[] lineCoords = {start, end}; LineString line = factory.createLineString(lineCoords); if (zone.contains(line)) { DeviceLocationCreateRequest request = new DeviceLocationCreateRequest(); request.setLatitude(end.y); request.setLongitude(end.x); request.setElevation(0.0); request.setEventDate(new Date(current)); IDeviceLocation created = getDeviceManagement().addDeviceLocation(assignment.getToken(), request); results.add(created); cx = cx + deltaX; cy = cy + deltaY; foundNext = true; } else { // Rotate deltas and try again. Coordinate delta = new Coordinate(deltaX, deltaY); xform.transform(delta, delta); deltaX = delta.x; deltaY = delta.y; } } current += 30000; } LOGGER.info(PREFIX_CREATE_EVENTS + " " + results.size() + " locations. "); return results; }