Draggable marker sample (#869)

This commit is contained in:
Frank Knoll
2021-08-14 15:06:21 +02:00
committed by Emux
parent ba8b800ee0
commit 9895921a5c
10 changed files with 493 additions and 0 deletions

View File

@@ -34,6 +34,9 @@
<activity
android:name=".ClusterMarkerOverlayActivity"
android:configChanges="keyboardHidden|orientation|screenSize" />
<activity
android:name=".DraggableMarkerOverlayActivity"
android:configChanges="keyboardHidden|orientation|screenSize" />
<activity
android:name=".FragmentActivity"
android:configChanges="keyboardHidden|orientation|screenSize" />

View File

@@ -0,0 +1,10 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.oscim.android.drag.DragMapView
android:id="@+id/mapView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</RelativeLayout>

View File

@@ -0,0 +1,26 @@
/*
* Copyright 2021 Frank Knoll
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.oscim.android.drag;
import org.oscim.core.GeoPoint;
public interface DragAndDropListener {
void startDragItemAtGeoPoint(DraggableMarkerItem item, GeoPoint geoPoint);
void ongoingDragItemToGeoPoint(DraggableMarkerItem item, GeoPoint geoPoint);
void dropItemAtGeoPoint(DraggableMarkerItem item, GeoPoint geoPoint);
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright 2013 Hannes Janetzek
* Copyright 2016 devemux86
* Copyright 2021 Frank Knoll
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.oscim.android.drag;
import android.view.MotionEvent;
import org.oscim.android.input.AndroidMotionEvent;
import org.oscim.android.input.GestureHandler;
import org.oscim.event.Gesture;
import org.oscim.map.Map;
class DragGestureHandler extends GestureHandler {
public static final Gesture START_DRAG = new Gesture() {
};
public static final Gesture ONGOING_DRAG = new Gesture() {
};
public static final Gesture END_DRAG = new Gesture() {
};
private final AndroidMotionEvent mMotionEvent;
private final Map mMap;
private boolean scrolling = false;
public DragGestureHandler(Map map) {
super(map);
mMotionEvent = new AndroidMotionEvent();
mMap = map;
}
public boolean isScrolling() {
return scrolling;
}
public void setScrolling(boolean scrolling) {
this.scrolling = scrolling;
}
@Override
public void onShowPress(MotionEvent e) {
scrolling = true;
mMap.handleGesture(START_DRAG, mMotionEvent.wrap(e));
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
scrolling = true;
return mMap.handleGesture(ONGOING_DRAG, mMotionEvent.wrap(e2));
}
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright 2012 Hannes Janetzek
* Copyright 2016-2020 devemux86
* Copyright 2018-2019 Gustl22
* Copyright 2021 Frank Knoll
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.oscim.android.drag;
import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import org.oscim.android.MapView;
import org.oscim.map.Map;
import org.oscim.utils.Parameters;
public class DragMapView extends MapView {
private DragGestureHandler gestureHandler;
public DragMapView(Context context) {
super(context);
}
public DragMapView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
if (!Parameters.MAP_EVENT_LAYER2) {
gestureHandler = new DragGestureHandler(mMap);
mGestureDetector = new GestureDetector(context, gestureHandler);
mGestureDetector.setOnDoubleTapListener(gestureHandler);
}
}
@Override
public boolean onTouchEvent(android.view.MotionEvent motionEvent) {
if (!isClickable()) {
return false;
}
if (motionEvent.getAction() == android.view.MotionEvent.ACTION_UP) {
if (gestureHandler.isScrolling()) {
gestureHandler.setScrolling(false);
return ((Map) mMap).handleGesture(DragGestureHandler.END_DRAG, mMotionEvent.wrap(motionEvent));
}
}
return super.onTouchEvent(motionEvent);
}
}

View File

@@ -0,0 +1,82 @@
/*
* Copyright 2012 osmdroid authors: Nicolas Gramlich, Theodore Hong, Fred Eisele
*
* Copyright 2013 Hannes Janetzek
* Copyright 2016-2021 devemux86
* Copyright 2016 Stephan Leuschner
* Copyright 2016 Pedinel
* Copyright 2019 Carlos Alberto Martínez Gadea
* Copyright 2021 Frank Knoll
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.oscim.android.drag;
import org.oscim.core.GeoPoint;
import org.oscim.event.Gesture;
import org.oscim.event.GestureListener;
import org.oscim.event.MotionEvent;
import org.oscim.layers.marker.ItemizedLayer;
import org.oscim.layers.marker.MarkerInterface;
import org.oscim.layers.marker.MarkerSymbol;
import org.oscim.map.Map;
import java.util.List;
import static org.oscim.android.drag.DragGestureHandler.*;
public class DraggableItemizedLayer extends ItemizedLayer implements GestureListener {
private final ItemDragger itemDragger;
public DraggableItemizedLayer(Map map,
List<MarkerInterface> markerItems,
MarkerSymbol defaultMarker,
OnItemGestureListener<MarkerInterface> listener) {
super(map, markerItems, defaultMarker, listener);
itemDragger = new ItemDragger(this, map);
}
@Override
protected boolean activateSelectedItems(MotionEvent event, ActiveItem task) {
return super.activateSelectedItems(event, task);
}
protected List<MarkerInterface> getMarkerItems() {
return mItemList;
}
@Override
public boolean onGesture(Gesture gesture, MotionEvent event) {
if (!isEnabled()) {
return false;
}
if (gesture == START_DRAG) {
return itemDragger.startDragItem(event, getGeoPoint(event));
} else if (gesture == ONGOING_DRAG) {
return itemDragger.ongoingDragItemTo(getGeoPoint(event));
} else if (gesture == END_DRAG) {
return itemDragger.dropItemAt(getGeoPoint(event));
} else {
itemDragger.noDrag();
}
return super.onGesture(gesture, event);
}
private GeoPoint getGeoPoint(MotionEvent event) {
return map().viewport().fromScreenPoint(event.getX(), event.getY());
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright 2012 osmdroid authors:
* Copyright 2012 Nicolas Gramlich
* Copyright 2012 Theodore Hong
* Copyright 2012 Fred Eisele
*
* Copyright 2014 Hannes Janetzek
* Copyright 2016 devemux86
* Copyright 2016 Erik Duisters
* Copyright 2017 Longri
* Copyright 2021 Frank Knoll
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.oscim.android.drag;
import org.oscim.core.GeoPoint;
import org.oscim.layers.marker.MarkerItem;
public class DraggableMarkerItem extends MarkerItem {
private final DragAndDropListener dragAndDropListener;
public DraggableMarkerItem(String title, String description, GeoPoint geoPoint, DragAndDropListener dragAndDropListener) {
super(title, description, geoPoint);
this.dragAndDropListener = dragAndDropListener;
}
public DragAndDropListener getDragAndDropListener() {
return dragAndDropListener;
}
}

View File

@@ -0,0 +1,96 @@
/*
* Copyright 2021 Frank Knoll
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.oscim.android.drag;
import org.oscim.core.GeoPoint;
import org.oscim.event.MotionEvent;
import org.oscim.layers.marker.ItemizedLayer;
import org.oscim.layers.marker.MarkerItem;
import org.oscim.layers.marker.MarkerLayer;
import org.oscim.map.Map;
class ItemDragger {
private final DraggableItemizedLayer draggableItemizedLayer;
private final DragAndDropListener dragItemAndRedrawListener;
private DraggableMarkerItem dragItem;
public ItemDragger(DraggableItemizedLayer draggableItemizedLayer, Map map) {
this.draggableItemizedLayer = draggableItemizedLayer;
this.dragItemAndRedrawListener = createDragItemAndRedrawListener(draggableItemizedLayer, map);
}
public boolean startDragItem(MotionEvent event, final GeoPoint geoPoint) {
dragItem = null;
return draggableItemizedLayer.activateSelectedItems(
event,
new ItemizedLayer.ActiveItem() {
@Override
public boolean run(int index) {
dragItem = (DraggableMarkerItem) draggableItemizedLayer.getMarkerItems().get(index);
dragItemAndRedrawListener.startDragItemAtGeoPoint(dragItem, geoPoint);
return true;
}
});
}
public boolean ongoingDragItemTo(GeoPoint geoPoint) {
if (dragItem == null) {
return false;
}
dragItemAndRedrawListener.ongoingDragItemToGeoPoint(dragItem, geoPoint);
return true;
}
public boolean dropItemAt(GeoPoint geoPoint) {
if (dragItem == null) {
return false;
}
dragItemAndRedrawListener.dropItemAtGeoPoint(dragItem, geoPoint);
return true;
}
public void noDrag() {
dragItem = null;
}
private DragAndDropListener createDragItemAndRedrawListener(final MarkerLayer markerLayer, final Map map) {
return new DragAndDropListener() {
@Override
public void startDragItemAtGeoPoint(DraggableMarkerItem item, GeoPoint geoPoint) {
item.getDragAndDropListener().startDragItemAtGeoPoint(item, geoPoint);
updateLocationOfMarkerItemAndRedraw(item, geoPoint);
}
@Override
public void ongoingDragItemToGeoPoint(DraggableMarkerItem item, GeoPoint geoPoint) {
item.getDragAndDropListener().ongoingDragItemToGeoPoint(item, geoPoint);
updateLocationOfMarkerItemAndRedraw(item, geoPoint);
}
@Override
public void dropItemAtGeoPoint(DraggableMarkerItem item, GeoPoint geoPoint) {
item.getDragAndDropListener().dropItemAtGeoPoint(item, geoPoint);
updateLocationOfMarkerItemAndRedraw(item, geoPoint);
}
private void updateLocationOfMarkerItemAndRedraw(MarkerItem markerItem, GeoPoint location) {
markerItem.geoPoint = location;
markerLayer.populate();
map.render();
}
};
}
}

View File

@@ -0,0 +1,105 @@
/*
* Copyright 2014 Hannes Janetzek
* Copyright 2016-2020 devemux86
* Copyright 2021 Frank Knoll
*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.oscim.android.test;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import org.oscim.android.canvas.AndroidBitmap;
import org.oscim.android.drag.DragAndDropListener;
import org.oscim.android.drag.DraggableItemizedLayer;
import org.oscim.android.drag.DraggableMarkerItem;
import org.oscim.core.GeoPoint;
import org.oscim.layers.marker.ItemizedLayer;
import org.oscim.layers.marker.MarkerInterface;
import org.oscim.layers.marker.MarkerSymbol;
import org.oscim.layers.marker.MarkerSymbol.HotspotPlace;
import org.oscim.layers.tile.bitmap.BitmapTileLayer;
import org.oscim.tiling.source.OkHttpEngine;
import org.oscim.tiling.source.UrlTileSource;
import org.oscim.tiling.source.bitmap.DefaultSources;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class DraggableMarkerOverlayActivity extends MapActivity {
public DraggableMarkerOverlayActivity() {
super(R.layout.activity_map_draggable);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
createLayers();
}
void createLayers() {
UrlTileSource tileSource = DefaultSources.OPENSTREETMAP
.httpFactory(new OkHttpEngine.OkHttpFactory())
.build();
tileSource.setHttpRequestHeaders(Collections.singletonMap("User-Agent", "vtm-android-example"));
mMap.layers().add(new BitmapTileLayer(mMap, tileSource));
ItemizedLayer mMarkerLayer = new DraggableItemizedLayer(
mMap,
new ArrayList<MarkerInterface>(),
new MarkerSymbol(
new AndroidBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.marker_poi)),
HotspotPlace.BOTTOM_CENTER),
null);
mMap.layers().add(mMarkerLayer);
DragAndDropListener dragAndDropListener = new DragAndDropListener() {
@Override
public void startDragItemAtGeoPoint(DraggableMarkerItem item, GeoPoint geoPoint) {
Log.i(DraggableMarkerOverlayActivity.this.getClass().getSimpleName(), "startDragItemAtGeoPoint: " + geoPoint);
}
@Override
public void ongoingDragItemToGeoPoint(DraggableMarkerItem item, GeoPoint geoPoint) {
Log.i(DraggableMarkerOverlayActivity.this.getClass().getSimpleName(), "ongoingDragItemToGeoPoint: " + geoPoint);
}
@Override
public void dropItemAtGeoPoint(DraggableMarkerItem item, GeoPoint geoPoint) {
Log.i(DraggableMarkerOverlayActivity.this.getClass().getSimpleName(), "dropItemAtGeoPoint: " + geoPoint);
}
};
List<MarkerInterface> pts = new ArrayList<>();
for (double lat = -90; lat <= 90; lat += 45) {
for (double lon = -180; lon <= 180; lon += 45) {
pts.add(new DraggableMarkerItem(lat + "/" + lon, "", new GeoPoint(lat, lon), dragAndDropListener));
}
}
mMarkerLayer.addItems(pts);
}
@Override
protected void onResume() {
super.onResume();
/* ignore saved position */
mMap.setMapPosition(0, 0, 1 << 2);
}
}

View File

@@ -124,6 +124,7 @@ public class Samples extends Activity {
linearLayout.addView(createButton(JeoIndoorActivity.class));
linearLayout.addView(createButton(GdxPoi3DActivity.class));
linearLayout.addView(createButton(OverpassActivity.class));
linearLayout.addView(createButton(DraggableMarkerOverlayActivity.class));
linearLayout.addView(createButton(ClusterMarkerOverlayActivity.class));
linearLayout.addView(createButton(FragmentActivity.class));
}