es.emergya.ui.gis.GeometryConverter.java Source code

Java tutorial

Introduction

Here is the source code for es.emergya.ui.gis.GeometryConverter.java

Source

/*
 * Copyright (C) 2010, Emergya (http://www.emergya.es)
 *
 * @author <a href="mailto:jlrodriguez@emergya.es">Juan Lus Rodrguez</a>
 * @author <a href="mailto:marias@emergya.es">Mara Arias</a>
 *
 * This file is part of GoFleet
 *
 * This software is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This software 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * As a special exception, if you link this library with other files to
 * produce an executable, this library does not by itself cause the
 * resulting executable to be covered by the GNU General Public License.
 * This exception does not however invalidate any other reasons why the
 * executable file might be covered by the GNU General Public License.
 */
/**
 * 
 */
package es.emergya.ui.gis;

import org.apache.commons.lang.NotImplementedException;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openstreetmap.josm.data.coor.EastNorth;
import org.openstreetmap.josm.data.coor.LatLon;
import org.openstreetmap.josm.data.gpx.WayPoint;
import org.openstreetmap.josm.data.osm.Node;
import org.openstreetmap.josm.data.osm.OsmPrimitive;
import org.openstreetmap.josm.data.osm.Way;

import es.emergya.geo.util.UTM;

/**
 * 
 * Conversor entre distintos tipos de geometrias
 * 
 * @author marias
 * 
 */
public class GeometryConverter {
    private static final Log log = LogFactory.getLog(GeometryConverter.class);
    private static UTM UTMConverter = new UTM();

    /**
     * <p>
     * Ejemplos de sintaxis:
     * </p>
     * <ul>
     * <li>Punto: POINT(30 50)</li>
     * <li>Linea: LINESTRING(1 1, 5 5, 10 10, 20 20)</li>
     * <li>Multilinea: LINESTRING( (1 1, 5 5, 10 10, 20 20),(20 30, 10 15, 40
     * 5))</li>
     * <li>Poligono simple: POLYGON (0 0, 10 0, 10 10, 0 0)</li>
     * <li>Varios poligono en una sola geometria (multipoligono): POLYGON ( (0
     * 0, 10 0, 10 10, 0 10, 0 0),( 20 20, 20 40, 40 40, 40 20, 20 20) )</li>
     * <li>Geometrias de distinto tipo en un solo elemento:
     * GEOMETRYCOLLECTION(POINT(4 6),LINESTRING(4 6,7 10))</li>
     * <li>Punto vacio: POINT EMPTY</li>
     * <li>Multipoligono vacio: MULTIPOLYGON EMPTY</li>
     * </ul>
     * 
     * @param geometry
     * @return
     */
    public static OsmPrimitive wktToOsmPrimitive(String geometry) {
        OsmPrimitive resultado = null;

        if (geometry != null) {
            log.trace("Vamos a convertir " + geometry);
            String[] componentes = StringUtils.split(geometry, "(");

            String tipo = componentes[0];
            GeometryType type = null;

            if (tipo.equals("LINESTRING"))
                type = GeometryType.LINESTRING;
            else if (tipo.equals("MULTILINESTRING"))
                type = GeometryType.MULTILINESTRING;
            else if (tipo.equals("POINT"))
                type = GeometryType.POINT;
            else if (tipo.equals("MULTIPOINT"))
                type = GeometryType.MULTIPOINT;
            else if (tipo.equals("POLYGON"))
                type = GeometryType.POLYGON;
            else if (tipo.equals("MULTIPOLYGON"))
                type = GeometryType.MULTIPOLYGON;
            else
                type = GeometryType.UNKNOWN;

            switch (type) {
            case LINESTRING:
                log.trace("Reconocido a LINESTRING");
                resultado = new Way();
                if (componentes[1].length() < 1) {
                    log.error("componentes erroneas");
                } else {
                    String[] coordenadas = StringUtils
                            .split(componentes[1].substring(0, componentes[1].length() - 1), ",");
                    if (coordenadas.length == 0)
                        log.trace("No hay coordenadas, geometria vacia?");
                    long id = 0l;
                    for (String coordenada : coordenadas) {
                        log.trace("coordenadas: " + coordenada);
                        String[] numeros = StringUtils.split(coordenada, " ");
                        if (numeros.length != 2)
                            log.error("Numero de dimensiones incorrecto: " + numeros.length);
                        else {
                            try {
                                LatLon latlon = extractLatLon(numeros);
                                log.trace(latlon);
                                Node n = new Node(id++);
                                n.setCoor(latlon);
                                ((Way) resultado).addNode(n);
                            } catch (Exception e) {
                                log.error("Error calculando el nodo", e);
                            }
                        }
                    }
                }
                break;
            case POINT:
                log.trace("Reconocido a POINT");
                if (componentes[1].length() < 1) {
                    log.error("componentes erroneas");
                } else {
                    String coordenada = componentes[1].substring(0, componentes[1].length() - 1);
                    if (coordenada.length() == 0)
                        log.trace("No hay coordenadas, geometria vacia?");
                    log.trace("coordenadas: " + coordenada);
                    String[] numeros = StringUtils.split(coordenada, " ");
                    if (numeros.length != 2)
                        log.error("Numero de dimensiones incorrecto: " + numeros.length);
                    else {
                        try {
                            LatLon latlon = extractLatLon(numeros);
                            resultado = new Node(latlon);
                        } catch (Exception e) {
                            log.error("Error calculando el nodo", e);
                            e.printStackTrace();
                        }
                    }

                }
                break;
            default:
                throw new NotImplementedException("Aun no tenemos implementado este tipo de geometria: " + tipo);
            }
        }
        resultado.incomplete = false;
        return resultado;
    }

    /**
     * <p>
     * Ejemplos de sintaxis:
     * </p>
     * <ul>
     * <li>Punto: POINT(30 50)</li>
     * <li>Linea: LINESTRING(1 1, 5 5, 10 10, 20 20)</li>
     * <li>Multilinea: LINESTRING( (1 1, 5 5, 10 10, 20 20),(20 30, 10 15, 40
     * 5))</li>
     * <li>Poligono simple: POLYGON (0 0, 10 0, 10 10, 0 0)</li>
     * <li>Varios poligono en una sola geometria (multipoligono): POLYGON ( (0
     * 0, 10 0, 10 10, 0 10, 0 0),( 20 20, 20 40, 40 40, 40 20, 20 20) )</li>
     * <li>Geometrias de distinto tipo en un silo elemento:
     * GEOMETRYCOLLECTION(POINT(4 6),LINESTRING(4 6,7 10))</li>
     * <li>Punto vacio: POINT EMPTY</li>
     * <li>Multipoligono vacio: MULTIPOLYGON EMPTY</li>
     * </ul>
     * 
     * @param geometry
     * @return
     */
    public static WayPoint wktToWayPoint(String geometry) {
        WayPoint resultado = null;

        if (geometry != null) {
            log.trace("Vamos a convertir " + geometry);
            String[] componentes = StringUtils.split(geometry, "(");

            String tipo = componentes[0];
            GeometryType type = null;

            if (tipo.equals("LINESTRING"))
                type = GeometryType.LINESTRING;
            else if (tipo.equals("MULTILINESTRING"))
                type = GeometryType.MULTILINESTRING;
            else if (tipo.equals("POINT"))
                type = GeometryType.POINT;
            else if (tipo.equals("MULTIPOINT"))
                type = GeometryType.MULTIPOINT;
            else if (tipo.equals("POLYGON"))
                type = GeometryType.POLYGON;
            else if (tipo.equals("MULTIPOLYGON"))
                type = GeometryType.MULTIPOLYGON;
            else
                type = GeometryType.UNKNOWN;

            switch (type) {
            case POINT:
                log.trace("Reconocido a POINT");
                if (componentes[1].length() < 1) {
                    log.error("componentes erroneas");
                } else {
                    String coordenada = componentes[1].substring(0, componentes[1].length() - 1);
                    if (coordenada.length() == 0)
                        log.trace("No hay coordenadas, geometria vacia?");
                    log.trace("coordenadas: " + coordenada);
                    String[] numeros = StringUtils.split(coordenada, " ");
                    if (numeros.length != 2)
                        log.error("Numero de dimensiones incorrecto: " + numeros.length);
                    else {
                        try {
                            LatLon latlon = extractLatLon(numeros);
                            log.trace("LatLon del nuevo marcador: " + latlon);
                            resultado = new WayPoint(latlon);
                        } catch (Exception e) {
                            log.error("Error calculando el nodo", e);
                            e.printStackTrace();
                        }
                    }

                }
                break;
            default:
                throw new NotImplementedException("Aun no tenemos implementado este tipo de geometria: " + tipo);
            }
        }
        return resultado;
    }

    private static LatLon extractLatLon(String[] numeros) {
        Double x = new Double(numeros[0]);
        Double y = new Double(numeros[1]);
        EastNorth en = new EastNorth(x, y);

        LatLon latlon = UTMConverter.eastNorth2latlon(en);
        return latlon;
    }
}

enum GeometryType {
    POINT, LINESTRING, MULTILINESTRING, MULTIPOINT, POLYGON, MULTIPOLYGON, UNKNOWN;
}