
org.oscim.map.Layers Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of vtm Show documentation
Show all versions of vtm Show documentation
OpenGL vector map library written in Java - running on Android, iOS, Desktop and within the browser.
The newest version!
/*
* Copyright 2013 Hannes Janetzek
* Copyright 2016-2019 devemux86
* Copyright 2016 Andrey Novikov
* Copyright 2017 Longri
* Copyright 2018 Gustl22
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see .
*/
package org.oscim.map;
import org.oscim.event.Gesture;
import org.oscim.event.GestureListener;
import org.oscim.event.MotionEvent;
import org.oscim.layers.GroupLayer;
import org.oscim.layers.Layer;
import org.oscim.layers.tile.ZoomLimiter;
import org.oscim.map.Map.InputListener;
import org.oscim.map.Map.UpdateListener;
import org.oscim.renderer.LayerRenderer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public final class Layers extends AbstractList {
private static final Logger log = LoggerFactory.getLogger(Layers.class);
private final Map mMap;
private final Layer.EnableHandler mEnableHandler;
private final List mLayerList = new CopyOnWriteArrayList<>();
private final List mGroupList = new ArrayList<>();
private final java.util.Map mGroupIndex = new HashMap<>();
private boolean mDirtyLayers;
private LayerRenderer[] mLayerRenderer;
private Layer[] mLayers;
Layers(Map map) {
mMap = map;
mEnableHandler = new Layer.EnableHandler() {
@Override
public void changed(boolean enabled) {
mDirtyLayers = true;
}
};
}
@Override
public synchronized Layer get(int index) {
return mLayerList.get(index);
}
public synchronized List getGroups() {
return mGroupList;
}
@Override
public synchronized int size() {
return mLayerList.size();
}
@Override
public synchronized void add(int index, Layer layer) {
if (mLayerList.contains(layer)) {
log.warn("layer already exists");
return;
}
// bind added layer
if (layer instanceof UpdateListener)
mMap.events.bind((UpdateListener) layer);
if (layer instanceof InputListener)
mMap.input.bind((InputListener) layer);
// add zoom limit to tile manager
if (layer instanceof ZoomLimiter.IZoomLimiter)
((ZoomLimiter.IZoomLimiter) layer).addZoomLimit();
// bind added group layer
if (layer instanceof GroupLayer) {
GroupLayer groupLayer = (GroupLayer) layer;
for (Layer gl : groupLayer.layers) {
if (gl instanceof UpdateListener)
mMap.events.bind((UpdateListener) gl);
if (gl instanceof InputListener)
mMap.input.bind((InputListener) gl);
if (gl instanceof ZoomLimiter.IZoomLimiter)
((ZoomLimiter.IZoomLimiter) gl).addZoomLimit();
}
}
layer.setEnableHandler(mEnableHandler);
mLayerList.add(index, layer);
mDirtyLayers = true;
}
/**
* Add using layer groups.
*/
public synchronized void add(Layer layer, int group) {
if (mLayerList.contains(layer)) {
log.warn("layer already exists");
return;
}
int index = mGroupList.indexOf(group);
if (index < 0) {
log.warn("unknown / adding layer group" + group);
addGroup(group);
}
index++;
if (index == mGroupList.size())
add(layer);
else {
add(mGroupIndex.get(mGroupList.get(index)), layer);
for (int i = index; i < mGroupList.size(); i++) {
group = mGroupList.get(i);
mGroupIndex.put(group, mGroupIndex.get(group) + 1);
}
}
}
@Override
public synchronized Layer remove(int index) {
mDirtyLayers = true;
Layer remove = mLayerList.remove(index);
// unbind removed layer
if (remove instanceof UpdateListener)
mMap.events.unbind((UpdateListener) remove);
if (remove instanceof InputListener)
mMap.input.unbind((InputListener) remove);
// remove zoom limit from tile manager
if (remove instanceof ZoomLimiter.IZoomLimiter)
((ZoomLimiter.IZoomLimiter) remove).removeZoomLimit();
// unbind removed group layer
if (remove instanceof GroupLayer) {
GroupLayer groupLayer = (GroupLayer) remove;
for (Layer gl : groupLayer.layers) {
if (gl instanceof UpdateListener)
mMap.events.unbind((UpdateListener) gl);
if (gl instanceof InputListener)
mMap.input.unbind((InputListener) gl);
if (gl instanceof ZoomLimiter.IZoomLimiter)
((ZoomLimiter.IZoomLimiter) gl).removeZoomLimit();
}
}
// update layer group pointers
for (Integer group : mGroupIndex.keySet()) {
int pointer = mGroupIndex.get(group);
if (pointer > index)
mGroupIndex.put(group, pointer - 1);
}
remove.setEnableHandler(null);
return remove;
}
@Override
public synchronized Layer set(int index, Layer layer) {
if (mLayerList.contains(layer)) {
log.warn("layer already exists");
return layer;
}
// bind added layer
if (layer instanceof UpdateListener)
mMap.events.bind((UpdateListener) layer);
if (layer instanceof InputListener)
mMap.input.bind((InputListener) layer);
// add zoom limit to tile manager
if (layer instanceof ZoomLimiter.IZoomLimiter)
((ZoomLimiter.IZoomLimiter) layer).addZoomLimit();
// bind added group layer
if (layer instanceof GroupLayer) {
GroupLayer groupLayer = (GroupLayer) layer;
for (Layer gl : groupLayer.layers) {
if (gl instanceof UpdateListener)
mMap.events.bind((UpdateListener) gl);
if (gl instanceof InputListener)
mMap.input.bind((InputListener) gl);
if (gl instanceof ZoomLimiter.IZoomLimiter)
((ZoomLimiter.IZoomLimiter) gl).addZoomLimit();
}
}
layer.setEnableHandler(mEnableHandler);
mDirtyLayers = true;
Layer remove = mLayerList.set(index, layer);
// unbind replaced layer
if (remove instanceof UpdateListener)
mMap.events.unbind((UpdateListener) remove);
if (remove instanceof InputListener)
mMap.input.unbind((InputListener) remove);
// remove zoom limit from tile manager
if (remove instanceof ZoomLimiter.IZoomLimiter)
((ZoomLimiter.IZoomLimiter) remove).removeZoomLimit();
// unbind replaced group layer
if (remove instanceof GroupLayer) {
GroupLayer groupLayer = (GroupLayer) remove;
for (Layer gl : groupLayer.layers) {
if (gl instanceof UpdateListener)
mMap.events.unbind((UpdateListener) gl);
if (gl instanceof InputListener)
mMap.input.unbind((InputListener) gl);
if (gl instanceof ZoomLimiter.IZoomLimiter)
((ZoomLimiter.IZoomLimiter) gl).removeZoomLimit();
}
}
remove.setEnableHandler(null);
return remove;
}
public synchronized void addGroup(int group) {
if (mGroupList.contains(group)) {
log.warn("group " + group + " already exists");
return;
}
mGroupList.add(group);
mGroupIndex.put(group, mLayerList.size());
}
/**
* @see List#contains(Object)
*/
public synchronized boolean contains(Layer layer) {
return mLayerList.contains(layer);
}
/**
* @see List#contains(Object)
*/
public synchronized boolean containsGroup(int group) {
return mGroupList.contains(group);
}
/**
* Should only be used by MapRenderer.
*
* @return the current LayerRenderer as array.
*/
public synchronized LayerRenderer[] getLayerRenderer() {
if (mDirtyLayers)
updateLayers();
return mLayerRenderer;
}
synchronized void destroy() {
if (mDirtyLayers)
updateLayers();
for (Layer o : mLayers)
o.onDetach();
}
synchronized boolean handleGesture(Gesture g, MotionEvent e) {
if (mDirtyLayers)
updateLayers();
for (Layer o : mLayers) {
if (o instanceof GestureListener)
if (((GestureListener) o).onGesture(g, e))
return true;
if (o instanceof GroupLayer) {
GroupLayer groupLayer = (GroupLayer) o;
for (Layer gl : groupLayer.layers) {
if (gl instanceof GestureListener)
if (((GestureListener) gl).onGesture(g, e))
return true;
}
}
}
return false;
}
public synchronized void updateLayers() {
try {
mLayers = new Layer[mLayerList.size()];
int numRenderLayers = 0;
for (int i = 0, n = mLayerList.size(); i < n; i++) {
Layer o = mLayerList.get(i);
if (o.isEnabled() && o.getRenderer() != null)
numRenderLayers++;
if (o instanceof GroupLayer) {
GroupLayer groupLayer = (GroupLayer) o;
for (Layer gl : groupLayer.layers) {
if (gl.isEnabled() && gl.getRenderer() != null)
numRenderLayers++;
}
}
mLayers[n - i - 1] = o;
}
mLayerRenderer = new LayerRenderer[numRenderLayers];
for (int i = 0, cnt = 0, n = mLayerList.size(); i < n; i++) {
Layer o = mLayerList.get(i);
LayerRenderer l = o.getRenderer();
if (o.isEnabled() && l != null)
mLayerRenderer[cnt++] = l;
if (o instanceof GroupLayer) {
GroupLayer groupLayer = (GroupLayer) o;
for (Layer gl : groupLayer.layers) {
l = gl.getRenderer();
if (gl.isEnabled() && l != null)
mLayerRenderer[cnt++] = l;
}
}
}
mDirtyLayers = false;
} catch (Exception e) {
log.error(e.toString(), e);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy