Hi Steve,
What you need to do is to project your lineString using some other
Coordinate Reference System (CRS). For example, here in NZ, I use the
NZGD2000/NZTM projection (probably using the wrong words here), which
represents everything in terms of metres from a particular point.
Below is a fragment of my code to read a WGS88 Shapefile, which represents
everything in degrees, and transform it into NZGD2000. Once the transform
is done, you can measure everything on your map in metres.
Frank
/**
* Load a WGS84 WGS84Shapefile, converting it to NZGD2000/NZTM, and
adding it to the result collection.
*
* @param result
* @param filepath
*/
public static void load(DefaultFeatureCollection result, String filepath)
{
log.debug("Loading WGS84 shapefile " + filepath);
SimpleFeatureSource featureSource;
try {
FileDataStore store = FileDataStoreFinder.getDataStore(new
File(filepath));
featureSource = store.getFeatureSource();
SimpleFeatureType schema = featureSource.getSchema();
CoordinateReferenceSystem fileCRS =
schema.getCoordinateReferenceSystem();
// Convert envelope limits to file crs for filter
MathTransform fromNZTM = CRS.findMathTransform(Global.internalCRS,
fileCRS, true);
Envelope limits = JTS.transform(Global.limits, fromNZTM);
Filter filter = CQL.toFilter("BBOX(the_geom, " + limits.getMinX() +
", " + limits.getMinY() + ", " + limits.getMaxX() + ", " + limits.getMaxY()
+ ")");
SimpleFeatureCollection coll = featureSource.getFeatures(filter);
makeNZTM(result, coll);
} catch (IOException ex) {
log.fatal("File not found: WGS84 shapefile " + filepath);
} catch (FactoryException | TransformException | CQLException ex) {
log.fatal(ex.getMessage(), ex);
}
}
/**
* Convert a Collection to NZGD2000/NZTM, and adding it to the result
collection Used only for loading Towns
*
* @param result
* @param coll
*/
private static void makeNZTM(DefaultFeatureCollection result,
SimpleFeatureCollection coll) {
MathTransform toNZTM = null;
SimpleFeatureType schema = coll.getSchema();
CoordinateReferenceSystem fileCRS =
schema.getCoordinateReferenceSystem();
try {
toNZTM = CRS.findMathTransform(fileCRS, Global.internalCRS, true);
} catch (FactoryException ex) {
log.fatal(ex.getMessage(), ex);
}
// This forces instantiation of each feature, as well as converting to
the NZTM
try (SimpleFeatureIterator i1 = coll.features()) {
while (i1.hasNext()) {
SimpleFeature f = i1.next();
Geometry geometry = ((Geometry) f.getDefaultGeometry()).union();
try {
Geometry geometry2 = JTS.transform(geometry, toNZTM);
Feature f2 = new Feature(f.getID(), (String)
f.getAttribute("name"));
f2.setDefaultGeometry(geometry2);
log.trace(f2.getID());
result.add(f2);
} catch (MismatchedDimensionException | TransformException ex) {
log.fatal(ex.getMessage(), ex);
}
}
i1.close();
}
}
On Mon, Jan 5, 2015 at 4:58 PM, Steve Mitchell <stevecmitch...@gmail.com>
wrote:
> Hopefully this is a simple question. Assuming that I've built a LineString
> like this:
>
> final GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
>
> final LineString lineString =
> geometryFactory.createLineString(coordinateArray);
>
> And now I want to generate mile or kilometer markers along that LineString.
> Is there a way to get lineString.getLength() to return, say miles, instead of
> degrees? I want to avoid having to loop through and use the
> GeodeticCalculator for every pair of points if there is a smarter way to do
> that with a LineString.
>
> I've stubbed out what I want to do:
>
> public Coordinate[] generateLapMarkers(final LineString lineString) {
> final SpatialIndex index = new STRtree();
> final LocationIndexedLine indexedPolyline = new
> LocationIndexedLine(lineString);
> final LinearLocation startLocation = indexedPolyline.getStartIndex();
> final Envelope search = lineString.getEnvelopeInternal();
> search.expandBy(1);
> index.insert(search, indexedPolyline);
> final double totalMiles = lineString.getLength(); // Some trick for
> getLength to return meters or miles.
>
> final List<Coordinate> laps = new
> ArrayList<Coordinate>((int)Math.floor(totalMiles)-1);
>
> // Didn't know how else to get LocationIndexedLine other than to search
> for itself.
> final List<LocationIndexedLine> locationIndexedLines =
> index.query(search);
> final LocationIndexedLine locationIndexedLine =
> locationIndexedLines.get(0);
> for (int d = 1; d < totalMiles; d++) {
> // Extract point by miles. Do we have to convert d back into degrees
> (d * magicToConvertDegreesIntoMetersRelativeToStartLocation)
> // or can the index be set-up to use meters instead of degrees.
> laps.add(locationIndexedLine.extractPoint(startLocation, d));
> }
> return laps.toArray(new Coordinate[laps.size()]);
> }
>
>
>
> ------------------------------------------------------------------------------
> Dive into the World of Parallel Programming! The Go Parallel Website,
> sponsored by Intel and developed in partnership with Slashdot Media, is
> your
> hub for all things parallel software development, from weekly thought
> leadership blogs to news, videos, case studies, tutorials and more. Take a
> look and join the conversation now. http://goparallel.sourceforge.net
> _______________________________________________
> GeoTools-GT2-Users mailing list
> GeoTools-GT2-Users@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/geotools-gt2-users
>
>
------------------------------------------------------------------------------
Dive into the World of Parallel Programming! The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net
_______________________________________________
GeoTools-GT2-Users mailing list
GeoTools-GT2-Users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/geotools-gt2-users