org.geomajas.internal.service.GeoServiceImpl Maven / Gradle / Ivy
/*
* This file is part of Geomajas, a component framework for building
* rich Internet applications (RIA) with sophisticated capabilities for the
* display, analysis and management of geographic information.
* It is a building block that allows developers to add maps
* and other geographic data capabilities to their web applications.
*
* Copyright 2008-2010 Geosparc, http://www.geosparc.com, Belgium
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
package org.geomajas.internal.service;
import com.vividsolutions.jts.algorithm.InteriorPointArea;
import com.vividsolutions.jts.algorithm.InteriorPointLine;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.LinearRing;
import com.vividsolutions.jts.geom.MultiLineString;
import com.vividsolutions.jts.geom.MultiPolygon;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;
import org.geomajas.global.CrsInfo;
import org.geomajas.global.ExceptionCode;
import org.geomajas.global.GeomajasException;
import org.geomajas.layer.LayerException;
import org.geomajas.layer.feature.InternalFeature;
import org.geomajas.service.GeoService;
import org.geotools.geometry.jts.JTS;
import org.geotools.referencing.CRS;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.NoSuchAuthorityCodeException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Collection of utility functions concerning geometries.
*
* @author Joachim Van der Auwera
* @author Jan De Moerloose
* @author Pieter De Graef
*/
@Component()
public final class GeoServiceImpl implements GeoService {
@Autowired(required = false)
private Map crsDefinitions;
private Map crsCache =
new ConcurrentHashMap();
@PostConstruct
private void postConstruct() throws GeomajasException {
if (null != crsDefinitions) {
for (CrsInfo crsInfo : crsDefinitions.values()) {
try {
CoordinateReferenceSystem crs = CRS.parseWKT(crsInfo.getCrsWkt());
crsCache.put(crsInfo.getKey(), crs);
} catch (FactoryException e) {
throw new GeomajasException(e, ExceptionCode.CRS_DECODE_FAILURE_FOR_MAP, crsInfo.getKey());
}
}
}
}
public CoordinateReferenceSystem getCrs(String crs) throws LayerException {
try {
CoordinateReferenceSystem res = crsCache.get(crs);
if (null == res) {
res = CRS.decode(crs);
}
return res;
} catch (NoSuchAuthorityCodeException e) {
throw new LayerException(e, ExceptionCode.CRS_DECODE_FAILURE_FOR_MAP, crs);
} catch (FactoryException e) {
throw new LayerException(e, ExceptionCode.CRS_DECODE_FAILURE_FOR_MAP, crs);
}
}
/**
* Isn't there a method for this in GeoTools?
*
* @param crs
* CRS string in the form of 'EPSG:'.
* @return SRID as integer.
*/
public int getSridFromCrs(String crs) {
int crsInt;
if (crs.indexOf(':') != -1) {
crsInt = Integer.parseInt(crs.substring(crs.indexOf(':') + 1));
} else {
try {
crsInt = Integer.parseInt(crs);
} catch (Exception e) {
crsInt = 0;
}
}
return crsInt;
}
/**
* Unreliable but works if srids are same as EPSG numbers.
*
* @param crs reference system of EPSG type.
* @return SRID as integer.
*/
public int getSridFromCrs(CoordinateReferenceSystem crs) {
return getSridFromCrs(crs.getIdentifiers().iterator().next().toString());
}
/**
* @inheritDoc
*/
public MathTransform findMathTransform(CoordinateReferenceSystem sourceCrs,
CoordinateReferenceSystem targetCrs) throws GeomajasException {
try {
MathTransform transform;
try {
transform = CRS.findMathTransform(sourceCrs, targetCrs);
} catch (Exception e) {
transform = CRS.findMathTransform(sourceCrs, targetCrs, true);
}
return transform;
} catch (FactoryException fe) {
throw new GeomajasException(fe, ExceptionCode.CRS_TRANSFORMATION_NOT_POSSIBLE, sourceCrs, targetCrs);
}
}
/**
* @inheritDoc
*/
public Geometry transform(Geometry source, CoordinateReferenceSystem sourceCrs, CoordinateReferenceSystem targetCrs)
throws GeomajasException {
if (sourceCrs == targetCrs) {
// only works when the caching of the CRSs works
return source;
}
MathTransform mathTransform = findMathTransform(sourceCrs, targetCrs);
try {
return JTS.transform(source, mathTransform);
} catch (TransformException te) {
throw new GeomajasException(te, ExceptionCode.CRS_TRANSFORMATION_NOT_POSSIBLE, sourceCrs, targetCrs);
}
}
/**
* @inheritDoc
*/
public Coordinate calcDefaultLabelPosition(InternalFeature feature) {
Geometry geometry = feature.getGeometry();
Coordinate labelPoint;
if (geometry == null || geometry.isEmpty()) {
labelPoint = null;
} else if (geometry.isValid()) {
if (geometry instanceof Polygon || geometry instanceof MultiPolygon) {
com.vividsolutions.jts.geom.Coordinate c;
try {
InteriorPointArea ipa = new InteriorPointArea(geometry);
c = ipa.getInteriorPoint();
} catch (Throwable t) {
// BUG in JTS for some valid geometries ? fall back to
// centroid
c = geometry.getCentroid().getCoordinate();
}
return new Coordinate(c);
} else if (geometry instanceof LineString || geometry instanceof MultiLineString) {
InteriorPointLine ipa = new InteriorPointLine(geometry);
com.vividsolutions.jts.geom.Coordinate c = ipa.getInteriorPoint();
labelPoint = new Coordinate(c);
} else {
labelPoint = geometry.getCentroid().getCoordinate();
}
} else {
labelPoint = geometry.getCentroid().getCoordinate();
}
if (null != labelPoint && (Double.isNaN(labelPoint.x) || Double.isNaN(labelPoint.y))) {
labelPoint = new Coordinate(geometry.getCoordinate());
}
return labelPoint;
}
/**
* @inheritDoc
*/
public Geometry createCircle(final Point point, final double radius, final int nrPoints) {
double x = point.getX();
double y = point.getY();
Coordinate[] coords = new Coordinate[nrPoints + 1];
for (int i = 0; i < nrPoints; i++) {
double angle = ((double) i / (double) nrPoints) * Math.PI * 2.0;
double dx = Math.cos(angle) * radius;
double dy = Math.sin(angle) * radius;
coords[i] = new Coordinate(x + dx, y + dy);
}
coords[nrPoints] = coords[0];
LinearRing ring = point.getFactory().createLinearRing(coords);
return point.getFactory().createPolygon(ring, null);
}
} © 2015 - 2025 Weber Informatics LLC | Privacy Policy