Skip to content

Instantly share code, notes, and snippets.

@DaniSagan
Last active December 5, 2018 17:17
Show Gist options
  • Save DaniSagan/67b3564fb27bdffaad36 to your computer and use it in GitHub Desktop.
Save DaniSagan/67b3564fb27bdffaad36 to your computer and use it in GitHub Desktop.
Utilidades para SigPac
package com.danisagan.sigpacvisor.utils;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import com.danisagan.common.Vec2d;
import com.danisagan.common.Vec2i;
import com.danisagan.sigpacvisor.data.Coords;
/**
* Clase con utilidades para transformación de coordenadas y descarga de imágenes desde Sigpac.
* @author daniel
*
*/
public class SigpacUtils {
/**
* Función que transforma una posición en el sistema SigPac a coordenadas GPS
* @param position Posición en el sistema SigPac a nivel de zoom 20
* @return Coordenadas GPS (datum WGS84/ETRS89)
*/
public static Coords coordsForPos(Vec2d position) {
// resolución de la cuadrícula
int n = 1 << 20;
// var auxiliares
double x = position.x;
double y = position.y;
// longitud en radianes
double lon = (x * 2. * Math.PI) / (double)n - Math.PI;
// var auxiliar
double yMap = (y * 2. * Math.PI) / (double)n - Math.PI;
// latitud en radianes
double lat = 2.*Math.atan(Math.exp(yMap)) - Math.PI/2.;
// coordenadas transformadas a grados
return new Coords(lat*180./Math.PI, lon*180./Math.PI);
}
/**
* Función que transforma unas coordenadas GPS al sistema SigPac
* @param coordinates Coordenadas del SigPac
* @return Posición en el sistema SigPac a nivel de zoom 20
*/
public static Vec2d posForCoords(Coords coordinates) {
// resolución de la cuadrícula
int n = 1 << 20;
// latitud y longitud en radianes
double lat = coordinates.getLatitude() * Math.PI / 180.;
double lon = coordinates.getLongitude() * Math.PI / 180.;
// posición x en el sistema Sigpac
double x = (double)n * (lon + Math.PI) / (2. * Math.PI);
// posición x en el sistema Sigpac
double y = ((double)n/(2.*Math.PI))*(Math.log(Math.tan(lat/2. + Math.PI/4.)) + Math.PI);
return new Vec2d(x, y);
}
/**
* Función que descarga una imagen desde el servidor de SigPac
* @param zoomLevel Nivel de zoom
* @param id ID de la cuadrícula
* @param outputFile Fichero donde se descargará la imagen
*/
public static void downloadImage(int zoomLevel, Vec2i id, File outputFile) {
BufferedImage image = null;
try {
URL url = new URL(getURL(zoomLevel, id));
image = ImageIO.read(url);
ImageIO.write(image, "jpg", outputFile);
} catch (IOException e) {
System.out.println("No se pudo descargar la imagen " + id.toString() + " z" + Integer.toString(zoomLevel));
e.printStackTrace();
// TODO Avisar de errores en la descarga
}
}
/**
* Función que devuelve la URL desde la cual descargar la imagen para la cuadrícula deseada.
* Si el nivel de zoom es 13 o menor descarga el plano correspondiente desde OpenStreetMap
* @param zoomLevel Nivel de zoom
* @param id ID de la cuadrícula
* @return URL desde la cual descargar la imagen
*/
public static String getURL(int zoomLevel, Vec2i id) {
if(zoomLevel >= 14) {
// URL para SigPac
return "http://sigpac.magrama.es/SDG/raster/ORTOFOTOS@3857/" + zoomLevel +
"." + id.x + "." + id.y + ".img";
} else {
int sizeY = 1 << zoomLevel;
// La posiciones en y en OpenStreetMap van al revés que en SigPac
int posY = sizeY-id.y-1;
int posX = id.x;
// URL del plano para OpenStreetMap
return "http://b.tile.openstreetmap.org/" + zoomLevel + "/" + posX + "/" + posY + ".png";
}
// TODO Planos para más sistemas (Google maps, Catastro, ...)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment