/*
* Geopaparazzi - Digital field mapping on Android based devices
* Copyright (C) 2016 HydroloGIS (www.hydrologis.com)
*
* This program 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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.geopaparazzi.core.mapview.overlays;
import android.graphics.Point;
import android.view.View;
import org.mapsforge.android.maps.MapView;
import org.mapsforge.android.maps.Projection;
import org.mapsforge.core.model.GeoPoint;
import org.mapsforge.core.model.MapPosition;
import org.mapsforge.core.util.MercatorProjection;
/**
* @author mapsforge
*
*/
public class SliderDrawProjection implements Projection {
private static final String INVALID_MAP_VIEW_DIMENSIONS = "invalid MapView dimensions";
private final MapView mapView;
private View view;
/**
* Constructor.
*
* @param mapView the map view.
* @param view the parent view.
*/
public SliderDrawProjection( MapView mapView, View view ) {
this.mapView = mapView;
this.view = view;
}
public GeoPoint fromPixels( int x, int y ) {
if (this.view.getWidth() <= 0 || this.view.getHeight() <= 0) {
return null;
}
MapPosition mapPosition = this.mapView.getMapPosition().getMapPosition();
// calculate the pixel coordinates of the top left corner
GeoPoint geoPoint = mapPosition.geoPoint;
double pixelX = MercatorProjection.longitudeToPixelX(geoPoint.getLongitude(), mapPosition.zoomLevel);
double pixelY = MercatorProjection.latitudeToPixelY(geoPoint.getLatitude(), mapPosition.zoomLevel);
pixelX -= this.view.getWidth() >> 1;
pixelY -= this.view.getHeight() >> 1;
// convert the pixel coordinates to a GeoPoint and return it
double lat = MercatorProjection.pixelYToLatitude(pixelY + y, mapPosition.zoomLevel);
double lon = MercatorProjection.pixelXToLongitude(pixelX + x, mapPosition.zoomLevel);
if (lat < -90 || lat > 90) {
return new GeoPoint(0, 0);
}
if (lon < -180 || lon > 180) {
return new GeoPoint(0, 0);
}
return new GeoPoint(lat, lon);
}
public int getLatitudeSpan() {
if (this.view.getWidth() > 0 && this.view.getHeight() > 0) {
GeoPoint top = fromPixels(0, 0);
GeoPoint bottom = fromPixels(0, this.view.getHeight());
return Math.abs(top.latitudeE6 - bottom.latitudeE6);
}
throw new IllegalStateException(INVALID_MAP_VIEW_DIMENSIONS);
}
public int getLongitudeSpan() {
if (this.view.getWidth() > 0 && this.view.getHeight() > 0) {
GeoPoint left = fromPixels(0, 0);
GeoPoint right = fromPixels(this.view.getWidth(), 0);
return Math.abs(left.longitudeE6 - right.longitudeE6);
}
throw new IllegalStateException(INVALID_MAP_VIEW_DIMENSIONS);
}
public float metersToPixels( float meters, byte zoom ) {
double latitude = this.mapView.getMapPosition().getMapCenter().getLatitude();
double groundResolution = MercatorProjection.calculateGroundResolution(latitude, zoom);
return (float) (meters * (1 / groundResolution));
}
public Point toPixels( GeoPoint in, Point out ) {
if (this.view.getWidth() <= 0 || this.view.getHeight() <= 0) {
return null;
}
MapPosition mapPosition = this.mapView.getMapPosition().getMapPosition();
// calculate the pixel coordinates of the top left corner
GeoPoint geoPoint = mapPosition.geoPoint;
double pixelX = MercatorProjection.longitudeToPixelX(geoPoint.getLongitude(), mapPosition.zoomLevel);
double pixelY = MercatorProjection.latitudeToPixelY(geoPoint.getLatitude(), mapPosition.zoomLevel);
pixelX -= this.view.getWidth() >> 1;
pixelY -= this.view.getHeight() >> 1;
if (out == null) {
// create a new point and return it
return new Point((int) (MercatorProjection.longitudeToPixelX(in.getLongitude(), mapPosition.zoomLevel) - pixelX),
(int) (MercatorProjection.latitudeToPixelY(in.getLatitude(), mapPosition.zoomLevel) - pixelY));
}
// reuse the existing point
out.x = (int) (MercatorProjection.longitudeToPixelX(in.getLongitude(), mapPosition.zoomLevel) - pixelX);
out.y = (int) (MercatorProjection.latitudeToPixelY(in.getLatitude(), mapPosition.zoomLevel) - pixelY);
return out;
}
public Point toPoint( GeoPoint in, Point out, byte zoom ) {
if (out == null) {
// create a new point and return it
return new Point((int) MercatorProjection.longitudeToPixelX(in.getLongitude(), zoom),
(int) MercatorProjection.latitudeToPixelY(in.getLatitude(), zoom));
}
// reuse the existing point
out.x = (int) MercatorProjection.longitudeToPixelX(in.getLongitude(), zoom);
out.y = (int) MercatorProjection.latitudeToPixelY(in.getLatitude(), zoom);
return out;
}
}