/*
* GeoSolutions Android Map Library - Digital field mapping on Android based devices
* Copyright (C) 2013 GeoSolutions (www.geo-solutions.it)
*
* 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 it.geosolutions.android.map.overlay.items;
import it.geosolutions.android.map.model.Feature;
import org.mapsforge.android.maps.MapViewPosition;
import org.mapsforge.android.maps.Projection;
import org.mapsforge.android.maps.overlay.Marker;
import org.mapsforge.core.model.BoundingBox;
import org.mapsforge.core.model.GeoPoint;
import org.mapsforge.core.model.Point;
import org.mapsforge.core.util.MercatorProjection;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
/**
* Described Highlighted Marker
* @author Lorenzo Natali (www.geo-solutions.it)
*
*/
public class DescribedMarker extends Marker {
/**
* The id of the marker
*/
private String id;
private String description;
private boolean highlight;
private int type;
private String source;
private String featureId;
private Feature feature;
private boolean textVisible = false;
public String getFeatureId() {
return featureId;
}
public void setFeatureId(String featureId) {
this.featureId = featureId;
}
//STROKE
private static final int FILL_COLOR = Color.BLUE;
private static final int FILL_ALPHA = 100;
private static final int STROKE_COLOR = Color.BLACK;
private static final int STROKE_ALPHA = 100;
private static final int STROKE_WIDTH = 3;
private static final Paint PAINT_STROKE=new Paint();
private static final Paint PAINT_FILL=new Paint();
private static final Paint PAINT_TEXT=new Paint();
/**
* Create a marker
* @param point
* @param boundCenterBottom
*/
public DescribedMarker(GeoPoint point, Drawable boundCenterBottom) {
super(point,boundCenterBottom);
createPaint();
}
/**
*
*/
private static void createPaint() {
// fill
PAINT_FILL.setStyle(Paint.Style.FILL);
PAINT_FILL.setColor(FILL_COLOR);
PAINT_FILL.setAlpha(FILL_ALPHA);
// border
PAINT_STROKE.setAntiAlias(true);
PAINT_STROKE.setColor(STROKE_COLOR);
PAINT_STROKE.setAlpha(STROKE_ALPHA);
PAINT_STROKE.setStrokeWidth(STROKE_WIDTH);
// text
PAINT_TEXT.setAntiAlias(true);
PAINT_TEXT.setColor(STROKE_COLOR);
PAINT_TEXT.setAlpha(STROKE_ALPHA);
PAINT_TEXT.setStrokeWidth(STROKE_WIDTH);
PAINT_TEXT.setTextSize(40);
PAINT_TEXT.setUnderlineText(true);
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public void highlightOn(){
highlight(true);
}
public void highlightOff(){
highlight(false);
}
public void highlight(boolean h){
highlight=h;
}
public boolean isHighlight(){
return highlight;
}
/**
* @return the textVisible
*/
public boolean isTextVisible() {
return textVisible;
}
/**
* @param textVisible the textVisible to set
*/
public void setTextVisible(boolean textVisible) {
this.textVisible = textVisible;
}
@Override
/* (non-Javadoc)
* @see org.mapsforge.android.maps.overlay.Marker#draw(org.mapsforge.core.model.BoundingBox, byte, android.graphics.Canvas, org.mapsforge.core.model.Point)
*/
public synchronized boolean draw(BoundingBox boundingBox, byte zoomLevel,
Canvas canvas, Point canvasPosition) {
GeoPoint geoPoint = this.getGeoPoint();
Drawable drawable = this.getDrawable();
if (geoPoint == null || drawable == null) {
return false;
}
double latitude = geoPoint.latitude;
double longitude = geoPoint.longitude;
int pixelX = (int) (MercatorProjection.longitudeToPixelX(longitude, zoomLevel) - canvasPosition.x);
int pixelY = (int) (MercatorProjection.latitudeToPixelY(latitude, zoomLevel) - canvasPosition.y);
Rect drawableBounds = drawable.copyBounds();
int left = pixelX + drawableBounds.left;
int top = pixelY + drawableBounds.top;
int right = pixelX + drawableBounds.right;
int bottom = pixelY + drawableBounds.bottom;
if (!intersect(canvas, left, top, right, bottom)) {
return false;
}
//TODO HighLight
if(isHighlight()){
canvas.drawCircle(pixelX, pixelY, drawableBounds.width()/2,PAINT_FILL) ;
canvas.drawCircle(pixelX, pixelY, drawableBounds.width()/2,PAINT_STROKE) ;
}
if(textVisible){
canvas.drawText(description, pixelX-40, pixelY+30, PAINT_TEXT);
}
drawable.setBounds(left, top, right, bottom);
drawable.draw(canvas);
drawable.setBounds(drawableBounds);
return true;
}
public boolean matchPoint(MapViewPosition mapViewPosition,Projection projection ,float x,float y) {
GeoPoint geoPoint = this.getGeoPoint();
Drawable drawable = this.getDrawable();
BoundingBox boundingBox = mapViewPosition.getBoundingBox();
byte zoomLevel =mapViewPosition.getZoomLevel();
double canvasPixelLeft = MercatorProjection.longitudeToPixelX(boundingBox.minLongitude, zoomLevel);
double canvasPixelTop = MercatorProjection.latitudeToPixelY(boundingBox.maxLatitude, zoomLevel);
Point canvasPosition = new Point(canvasPixelLeft, canvasPixelTop);
if (geoPoint == null || drawable == null) {
return false;
}
double latitude = geoPoint.latitude;
double longitude = geoPoint.longitude;
int pixelX = (int) (MercatorProjection.longitudeToPixelX(longitude, zoomLevel) - canvasPosition.x);
int pixelY = (int) (MercatorProjection.latitudeToPixelY(latitude, zoomLevel) - canvasPosition.y);
Rect drawableBounds = drawable.copyBounds();
int left = pixelX + drawableBounds.left;
int top = pixelY + drawableBounds.top;
int right = pixelX + drawableBounds.right;
int bottom = pixelY + drawableBounds.bottom;
if(intersect(x,y,left,top,right,bottom)){
return true;
}
return false;
//TODO translate x and y in pixels
}
/**
* return the x y position of the marker relative to the point
* @param canvasPosition
* @param zoomLevel
* @return
*/
public Point getXY(MapViewPosition mapViewPosition,Projection projection){
GeoPoint geoPoint = this.getGeoPoint();
Drawable drawable = this.getDrawable();
if (geoPoint == null || drawable == null) {
return null;
}
BoundingBox boundingBox = mapViewPosition.getBoundingBox();
byte zoomLevel =mapViewPosition.getZoomLevel();
double canvasPixelLeft = MercatorProjection.longitudeToPixelX(boundingBox.minLongitude, zoomLevel);
double canvasPixelTop = MercatorProjection.latitudeToPixelY(boundingBox.maxLatitude, zoomLevel);
Point canvasPosition = new Point(canvasPixelLeft, canvasPixelTop);
double latitude = geoPoint.latitude;
double longitude = geoPoint.longitude;
int pixelX = (int) (MercatorProjection.longitudeToPixelX(longitude, zoomLevel) - canvasPosition.x);
int pixelY = (int) (MercatorProjection.latitudeToPixelY(latitude, zoomLevel) - canvasPosition.y);
return new Point(pixelX, pixelY);
}
/**
* Move the GeoPoint to a certain point related to the mapViewPosition
* @param x
* @param y
* @param mapViewPosition
* @param projectionl
*/
public void setXY(double x, double y, MapViewPosition mapViewPosition,Projection projectionl){
BoundingBox boundingBox = mapViewPosition.getBoundingBox();
byte zoomLevel =mapViewPosition.getZoomLevel();
double canvasPixelLeft = MercatorProjection.longitudeToPixelX(boundingBox.minLongitude, zoomLevel);
double canvasPixelTop = MercatorProjection.latitudeToPixelY(boundingBox.maxLatitude, zoomLevel);
double lon = MercatorProjection.pixelXToLongitude(x+canvasPixelLeft, zoomLevel);
double lat = MercatorProjection.pixelYToLatitude(y+canvasPixelTop, zoomLevel);
setGeoPoint(new GeoPoint(lat, lon));
}
/**
* @param x
* @param y
* @param left
* @param top
* @param right
* @param bottom
* @return
*/
private boolean intersect(float x, float y, int left, int top, int right,
int bottom) {
return x >=left && x<=right && y >=top && y <=bottom;
}
/**
* Recreated because is not visible
* @param canvas
* @param left
* @param top
* @param right
* @param bottom
* @return
*/
private static boolean intersect(Canvas canvas, float left, float top, float right, float bottom) {
return right >= 0 && left <= canvas.getWidth() && bottom >= 0 && top <= canvas.getHeight();
}
/**
* @param type
*/
public void setType(int type) {
this.type=type;
}
public int getType(){
return type;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public Feature getFeature() {
return feature;
}
public void setFeature(Feature feature) {
this.feature = feature;
}
}