package mil.nga.dice.map.geopackage;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.TileOverlay;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import mil.nga.dice.R;
import mil.nga.geopackage.BoundingBox;
import mil.nga.geopackage.map.geom.GoogleMapShape;
import mil.nga.geopackage.map.geom.GoogleMapShapeType;
import mil.nga.geopackage.projection.Projection;
import mil.nga.geopackage.projection.ProjectionConstants;
import mil.nga.geopackage.projection.ProjectionFactory;
import mil.nga.geopackage.map.tiles.overlay.FeatureOverlayQuery;
import mil.nga.geopackage.tiles.overlay.FeatureTableData;
/**
* Map data managed for a single GeoPackage table
*/
public class GeoPackageTableMapData {
/**
* Tile overlay added to the map view
*/
private TileOverlay tileOverlay;
/**
* Feature overlay queries for handling map click queries
*/
private List<FeatureOverlayQuery> featureOverlayQueries;
/**
* Map shapes added to the map view
*/
private List<GoogleMapShape> mapShapes = new ArrayList<>();
/**
* Table name
*/
private String name;
/**
* Enabled state
*/
private boolean enabled;
/**
* Projection
*/
private Projection projection;
/**
* True if feature table, false if tile table
*/
private boolean featureTable;
/**
* Table count
*/
private int count;
/**
* Min zoom level
*/
private long minZoom;
/**
* Max zoom level
*/
private long maxZoom;
/**
* Linked table map data
*/
private List<GeoPackageTableMapData> linked = new ArrayList<>();
/**
* Constructor
*
* @param name table name
* @param featureTable true for feature table, false for tile table
*/
public GeoPackageTableMapData(String name, boolean featureTable) {
this.name = name;
projection = ProjectionFactory.getProjection(ProjectionConstants.EPSG_WORLD_GEODETIC_SYSTEM);
this.featureTable = featureTable;
}
/**
* Get the tile overlay
*
* @return tile overlay
*/
public TileOverlay getTileOverlay() {
return tileOverlay;
}
/**
* Set the tile overlay
*
* @param tileOverlay tile overlay
*/
public void setTileOverlay(TileOverlay tileOverlay) {
this.tileOverlay = tileOverlay;
}
/**
* Get the feature overlay queries
*
* @return feature overlay queries
*/
public List<FeatureOverlayQuery> getFeatureOverlayQueries() {
return featureOverlayQueries;
}
/**
* Set the feature overlay queries
*
* @param featureOverlayQueries feature overlay queries
*/
public void setFeatureOverlayQueries(List<FeatureOverlayQuery> featureOverlayQueries) {
this.featureOverlayQueries = featureOverlayQueries;
}
/**
* Get the map shapes
*
* @return map shapes
*/
public List<GoogleMapShape> getMapShapes() {
return mapShapes;
}
/**
* Get the GeoPackage table name
*
* @return table name
*/
public String getName() {
return name;
}
/**
* Is the GeoPackage table enabled
*
* @return true if enabled
*/
public boolean isEnabled() {
return enabled;
}
/**
* Set the table enabled state
*
* @param enabled true if enabled
*/
public void setEnabled(boolean enabled) {
this.enabled = enabled;
for (GeoPackageTableMapData linkedTable : linked) {
linkedTable.setEnabled(enabled);
}
}
/**
* Get the table data count
*
* @return count
*/
public int getCount() {
return count;
}
/**
* Set the table data count
*
* @param count count
*/
public void setCount(int count) {
this.count = count;
}
/**
* Get the min zoom
*
* @return min zoom
*/
public long getMinZoom() {
return minZoom;
}
/**
* Set the min zoom
*
* @param minZoom min zoom
*/
public void setMinZoom(long minZoom) {
this.minZoom = minZoom;
}
/**
* Get the max zoom
*
* @return max zoom
*/
public long getMaxZoom() {
return maxZoom;
}
/**
* Set the max zoom
*
* @param maxZoom max zoom
*/
public void setMaxZoom(long maxZoom) {
this.maxZoom = maxZoom;
}
/**
* Get the linked tables
*
* @return linked tables
*/
public List<GeoPackageTableMapData> getLinked() {
return linked;
}
/**
* Add a linked table
*
* @param link linked table
*/
public void addLinked(GeoPackageTableMapData link) {
linked.add(link);
}
/**
* Add a feature overlay query to the table
*
* @param query feature overlay query
*/
public void addFeatureOverlayQuery(FeatureOverlayQuery query) {
if (featureOverlayQueries == null) {
featureOverlayQueries = new ArrayList<>();
}
featureOverlayQueries.add(query);
}
/**
* Add a map shape to the table
*
* @param shape map shape
*/
public void addMapShape(GoogleMapShape shape) {
mapShapes.add(shape);
}
/**
* Remove the GeoPackage table from the map
*
* @param markerIds
*/
public void removeFromMap(Map<String, ?> markerIds) {
if (tileOverlay != null) {
tileOverlay.remove();
tileOverlay = null;
}
for (GoogleMapShape shape : mapShapes) {
if(shape.getShapeType() == GoogleMapShapeType.MARKER){
Marker marker = (Marker) shape.getShape();
markerIds.remove(marker.getId());
}
shape.remove();
}
mapShapes.clear();
close();
}
/**
* Close the table map data connection
*/
public void close() {
if (featureOverlayQueries != null) {
for (FeatureOverlayQuery featureOverlayQuery : featureOverlayQueries) {
featureOverlayQuery.close();
}
for (GeoPackageTableMapData linkedMapData : linked) {
linkedMapData.close();
}
}
}
/**
* Query and build a map click location message from GeoPackage table
*
* @param latLng click location
* @param mapView map view
* @param map map
* @return click message
*/
public String mapClickMessage(LatLng latLng, MapView mapView, GoogleMap map) {
StringBuilder message = null;
if (featureOverlayQueries != null) {
for (FeatureOverlayQuery featureOverlayQuery : featureOverlayQueries) {
String overlayMessage = featureOverlayQuery.buildMapClickMessage(latLng, mapView, map, projection);
if (overlayMessage != null) {
if (message == null) {
message = new StringBuilder();
} else {
message.append("\n\n");
}
message.append(overlayMessage);
}
}
}
return message != null ? message.toString() : null;
}
/**
* Query and build a map click location message from GeoPackage table
*
* @param latLng click location
* @param zoom zoom level
* @param mapBounds map bounds
* @return click message
*/
public String mapClickMessage(LatLng latLng, double zoom, BoundingBox mapBounds) {
StringBuilder message = null;
if (featureOverlayQueries != null) {
for (FeatureOverlayQuery featureOverlayQuery : featureOverlayQueries) {
String overlayMessage = featureOverlayQuery.buildMapClickMessageWithMapBounds(latLng, zoom, mapBounds, projection);
if (overlayMessage != null) {
if (message == null) {
message = new StringBuilder();
} else {
message.append("\n\n");
}
message.append(overlayMessage);
}
}
}
return message != null ? message.toString() : null;
}
/**
* Query and build map click table data from GeoPackage table
*
* @param latLng click location
* @param mapView map view
* @param map map
* @return click table data
*/
public FeatureTableData mapClickTableData(LatLng latLng, MapView mapView, GoogleMap map) {
FeatureTableData tableData = null;
if (featureOverlayQueries != null) {
for (FeatureOverlayQuery featureOverlayQuery : featureOverlayQueries) {
tableData = featureOverlayQuery.buildMapClickTableData(latLng, mapView, map, projection);
}
}
return tableData;
}
/**
* Query and build map click table data from GeoPackage table
*
* @param latLng click location
* @param zoom zoom level
* @param mapBounds map bounds
* @return click table data
*/
public FeatureTableData mapClickTableData(LatLng latLng, double zoom, BoundingBox mapBounds) {
FeatureTableData tableData = null;
if (featureOverlayQueries != null) {
for (FeatureOverlayQuery featureOverlayQuery : featureOverlayQueries) {
tableData = featureOverlayQuery.buildMapClickTableDataWithMapBounds(latLng, zoom, mapBounds, projection);
}
}
return tableData;
}
/**
* Get the table icon image resource id
*
* @return image resource id
*/
public Integer getIconImageResourceId() {
Integer icon = null;
if (featureTable) {
icon = R.drawable.ic_place;
} else {
icon = R.drawable.ic_tiles;
}
return icon;
}
/**
* Get the table information
*
* @return table info
*/
public String getInfo() {
String info = null;
if (featureTable) {
info = "features";
} else {
info = "tiles";
}
long min = minZoom;
long max = maxZoom;
for (GeoPackageTableMapData linkedTable : linked) {
min = Math.min(min, linkedTable.getMinZoom());
max = Math.max(max, linkedTable.getMaxZoom());
}
info += ": " + count + ", zoom: " + min + " - " + max;
return info;
}
}