use of org.locationtech.jts.geom.GeometryCollection in project hale by halestudio.
the class StreamGeometryWriter method write.
/**
* Write a geometry to a stream for a GML document
*
* @param writer the XML stream writer
* @param geometry the geometry
* @param property the geometry property
* @param srsName the SRS name of a common SRS for the whole document, may
* be <code>null</code>
* @param report the reporter
* @param decimalFormatter a decimal formatter to format geometry
* coordinates
* @throws XMLStreamException if any error occurs writing the geometry
*/
public void write(XMLStreamWriter writer, Geometry geometry, PropertyDefinition property, String srsName, IOReporter report, DecimalFormat decimalFormatter) throws XMLStreamException {
// write eventual required id
GmlWriterUtil.writeRequiredID(writer, property.getPropertyType(), null, false);
// write any srsName attribute on the parent element
writeSrsName(writer, property.getPropertyType(), geometry, srsName);
// write any srsDimension attribute on the parent element
writeSrsDimension(writer, property.getPropertyType(), geometry);
if (simplifyGeometry) {
// reduce to internal geometry
if (geometry instanceof GeometryCollection && ((GeometryCollection) geometry).getNumGeometries() == 1) {
geometry = geometry.getGeometryN(0);
}
}
Class<? extends Geometry> geomType = geometry.getClass();
// remember if we already found a solution to this problem
List<DefinitionPath> preferredPaths = restoreCandidate(property.getPropertyType(), geomType);
if (preferredPaths == null) {
// find candidates
List<DefinitionPath> candidates = findCandidates(property, geomType);
// if no candidate found, try with compatible geometries
Class<? extends Geometry> originalType = geomType;
Geometry originalGeometry = geometry;
ConversionLadder ladder = GeometryConverterRegistry.getInstance().createLadder(geometry);
while (candidates.isEmpty() && ladder.hasNext()) {
geometry = ladder.next();
geomType = geometry.getClass();
log.info(// $NON-NLS-1$
"Possible structure for writing " + originalType.getSimpleName() + " not found, trying " + geomType.getSimpleName() + // $NON-NLS-1$ //$NON-NLS-2$
" instead");
List<DefinitionPath> candPaths = restoreCandidate(property.getPropertyType(), geomType);
if (candPaths != null) {
// use stored candidate
candidates = new ArrayList<>(candPaths);
} else {
candidates = findCandidates(property, geomType);
}
}
if (candidates.isEmpty()) {
// also try the generic geometry type
geometry = originalGeometry;
geomType = Geometry.class;
log.info(// $NON-NLS-1$
"Possible structure for writing " + originalType.getSimpleName() + // $NON-NLS-1$ //$NON-NLS-2$
" not found, trying the generic geometry type instead");
List<DefinitionPath> candPaths = restoreCandidate(property.getPropertyType(), geomType);
if (candPaths != null) {
// use stored candidate
candidates = new ArrayList<>(candidates);
} else {
candidates = findCandidates(property, geomType);
}
// remember generic match for later
storeCandidate(property.getPropertyType(), originalType, sortPreferredCandidates(candidates, geomType));
}
for (DefinitionPath candidate : candidates) {
log.info(// $NON-NLS-1$ //$NON-NLS-2$
"Geometry structure match: " + geomType.getSimpleName() + " - " + candidate);
}
if (candidates.isEmpty()) {
log.error(// $NON-NLS-1$
"No geometry structure match for " + originalType.getSimpleName() + // $NON-NLS-1$
" found, writing WKT " + // $NON-NLS-1$
"representation instead");
writer.writeCharacters(originalGeometry.toText());
return;
}
// determine preferred candidate
preferredPaths = sortPreferredCandidates(candidates, geomType);
// remember for later
storeCandidate(property.getPropertyType(), geomType, preferredPaths);
}
DefinitionPath path = selectValidPath(preferredPaths, geometry);
if (path != null) {
// write geometry
writeGeometry(writer, geometry, path, srsName, decimalFormatter);
} else {
report.error(new IOMessageImpl("No valid path found for encoding geometry, geometry is skipped.", null));
}
}
use of org.locationtech.jts.geom.GeometryCollection in project hale by halestudio.
the class InstanceMarker method paintGeometry.
/**
* Paint a geometry.
*
* @param g the graphics to paint on
* @param crsDefinition the CRS definition associated with the geometry
* @param geometry the geometry
* @param context the context
* @param converter the pixel converter
* @param zoom the zoom level
* @param singleGeometry if this is the only geometry associated to the
* marker
* @param gBounds the graphics bounds
* @param mapCRS the map coordinate reference system
* @param calculateArea if the area representing the marker should be
* calculated, if <code>false</code> is given here the return
* value is ignored and should be <code>null</code>
* @return the area the geometry occupies (in pixel coordinates), or
* <code>null</code> if nothing has been painted
*/
protected Area paintGeometry(Graphics2D g, CRSDefinition crsDefinition, Geometry geometry, InstanceWaypoint context, PixelConverter converter, int zoom, boolean singleGeometry, Rectangle gBounds, CoordinateReferenceSystem mapCRS, boolean calculateArea) {
if (geometry instanceof GeometryCollection) {
// paint each geometry in a geometry collection
List<Area> areas = (calculateArea) ? (new ArrayList<Area>()) : (null);
GeometryCollection collection = (GeometryCollection) geometry;
for (int i = 0; i < collection.getNumGeometries(); i++) {
Geometry geom = collection.getGeometryN(i);
Area geomArea = paintGeometry(g, crsDefinition, geom, context, converter, zoom, singleGeometry && collection.getNumGeometries() == 1, gBounds, mapCRS, calculateArea);
if (areas != null && geomArea != null) {
areas.add(geomArea);
}
}
if (areas == null || areas.isEmpty()) {
return null;
} else {
return new MultiArea(areas);
}
}
// if it is the only geometry the check that was already made is OK
if (!calculateArea && !singleGeometry) {
// we can safely return null inside this method, as no area has to
// be calculated
// determine bounding box
BoundingBox geometryBB;
synchronized (geometryMapBBs) {
// retrieve cached bounding box
geometryBB = geometryMapBBs.get(geometry);
if (geometryBB == null) {
// if none available, try to calculate BB
BoundingBox calcBB = BoundingBox.compute(geometry);
if (calcBB != null && calcBB.checkIntegrity()) {
try {
// get CRS converter
CRSConverter conv = CRSConverter.getConverter(crsDefinition.getCRS(), mapCRS);
// manually convert to map CRS
geometryBB = conv.convert(calcBB);
// put BB in cache
geometryMapBBs.put(geometry, geometryBB);
} catch (Throwable e) {
log.error("Error checking geometry bounding box", e);
return null;
}
}
}
}
if (geometryBB != null) {
try {
GeoPosition minCorner = new GeoPosition(geometryBB.getMinX(), geometryBB.getMinY(), converter.getMapEpsg());
GeoPosition maxCorner = new GeoPosition(geometryBB.getMaxX(), geometryBB.getMaxY(), converter.getMapEpsg());
// determine pixel coordinates
Point2D minPixels = converter.geoToPixel(minCorner, zoom);
Point2D maxPixels = converter.geoToPixel(maxCorner, zoom);
// geometry pixel bounding box
int minX = Math.min((int) minPixels.getX(), (int) maxPixels.getX());
int minY = Math.min((int) minPixels.getY(), (int) maxPixels.getY());
int maxX = Math.max((int) minPixels.getX(), (int) maxPixels.getX());
int maxY = Math.max((int) minPixels.getY(), (int) maxPixels.getY());
// add overlap
minX -= GEOMETRY_PIXEL_BB_OVERLAP;
minY -= GEOMETRY_PIXEL_BB_OVERLAP;
maxX += GEOMETRY_PIXEL_BB_OVERLAP;
maxY += GEOMETRY_PIXEL_BB_OVERLAP;
// create bounding box
Rectangle geometryPixelBB = new Rectangle(minX, minY, maxX - minX, maxY - minY);
if (!gBounds.intersects(geometryPixelBB) && !gBounds.contains(geometryPixelBB)) {
// geometry does not lie in tile
return null;
}
} catch (Throwable e) {
log.error("Error checking geometry bounding box", e);
return null;
}
} else {
// empty or invalid bounding box
return null;
}
}
if (geometry instanceof Point) {
return paintPoint((Point) geometry, g, crsDefinition, context, converter, zoom, mapCRS, calculateArea);
}
if (geometry instanceof Polygon) {
return paintPolygon((Polygon) geometry, g, crsDefinition, context, converter, zoom, mapCRS, calculateArea);
}
if (geometry instanceof LineString) {
return paintLine((LineString) geometry, g, crsDefinition, context, converter, zoom, mapCRS, calculateArea);
}
return null;
}
use of org.locationtech.jts.geom.GeometryCollection in project ddf by codice.
the class KmlToJtsMultiGeometryConverterTest method testNullKmlMultiGeometryReturnsNullJtsGeometryCollection.
@Test
public void testNullKmlMultiGeometryReturnsNullJtsGeometryCollection() {
GeometryCollection geometryCollection = KmlToJtsMultiGeometryConverter.from(null);
assertThat(geometryCollection, nullValue());
}
use of org.locationtech.jts.geom.GeometryCollection in project OpenCarto by jgaffuri.
the class BasicStyle method draw.
@Override
public void draw(MultiScaleFeature f, int z, PointTransformation pt, Graphics2D gr) {
Geometry geom = f.getGeom(z);
if (geom instanceof Point)
draw((Point) geom, pt, gr);
else if (geom instanceof LineString)
draw((LineString) geom, pt, gr);
else if (geom instanceof Polygon)
draw((Polygon) geom, pt, gr);
else if (geom instanceof GeometryCollection)
draw((GeometryCollection) geom, pt, gr);
else
logger.log(Level.WARNING, "Method not implemented yet for geometry type: " + geom.getClass().getSimpleName());
}
use of org.locationtech.jts.geom.GeometryCollection in project hale by halestudio.
the class ExtentTransformation method calculateExtent.
/**
* Calculate the extent of a set of geometries.
*
* @param geometries the geometries or instances containing geometries
* @param type the type of extent to calculate
* @return the calculated extent
* @throws TransformationException if source geometries don't have a common
* CRS
* @throws NoResultException if the result extent would be <code>null</code>
*/
public static GeometryProperty<?> calculateExtent(Iterable<?> geometries, ExtentType type) throws TransformationException, NoResultException {
InstanceTraverser traverser = new DepthFirstInstanceTraverser(true);
GeometryFinder geoFind = new GeometryFinder(null);
GeometryFactory fact = new GeometryFactory();
CRSDefinition commonCrs = null;
Geometry[] geomsCollectingArray = new Geometry[SIMULTAN_PROCESS_GEOMS];
short geomsCollectedIdx = 0;
for (Object value : geometries) {
traverser.traverse(value, geoFind);
for (GeometryProperty<?> geom : geoFind.getGeometries()) {
// no CRS or one common CRS is OK
if (commonCrs == null) {
commonCrs = geom.getCRSDefinition();
} else {
if (geom.getCRSDefinition() != null && !geom.getCRSDefinition().equals(commonCrs)) {
// CRS doesn't match
throw new TransformationException("Source geometries don't have a common CRS.");
}
}
Geometry g = geom.getGeometry();
// If geometry collecting array not filled.
if (geomsCollectedIdx < SIMULTAN_PROCESS_GEOMS - 1) {
geomsCollectingArray[geomsCollectedIdx++] = g;
} else // Geometry collecting array filled.
{
// add last
geomsCollectingArray[geomsCollectedIdx] = g;
// geometry
GeometryCollection gc = new GeometryCollection(geomsCollectingArray, fact);
geomsCollectingArray[0] = resolveParam(gc, type);
geomsCollectedIdx = 1;
}
}
geoFind.reset();
}
Geometry extent = resolveParam(new GeometryCollection(Arrays.copyOfRange(geomsCollectingArray, 0, geomsCollectedIdx), fact), type);
if (extent != null) {
return new DefaultGeometryProperty<Geometry>(commonCrs, extent);
}
throw new NoResultException();
}
Aggregations