[Samples] added tap on map feature
This commit is contained in:
parent
fac27c2d29
commit
019638b4fa
6 changed files with 335 additions and 20 deletions
|
@ -28,9 +28,8 @@
|
|||
<item name="expandable_list_background">@color/list_item_light</item>
|
||||
<item name="osmo_header_background">@color/osmo_header_light</item>
|
||||
<item name="dashboard_subheader_text_color">@color/dashboard_subheader_text_light</item>
|
||||
<item name="dashboard_general_button_text_color">
|
||||
@color/dashboard_general_button_text_light
|
||||
</item>
|
||||
<item name="dashboard_general_button_text_color">@color/dashboard_general_button_text_light</item>
|
||||
<item name="expandable_list_item_background">@drawable/expandable_list_item_background_light</item>
|
||||
<item name="android:textColorPrimary">@color/color_black</item>
|
||||
<item name="spinnerItemTextColor">@color/color_black</item>
|
||||
<item name="spinnerListBackground">@color/spinner_list_background_light</item>
|
||||
|
|
|
@ -25,8 +25,8 @@ import android.view.View;
|
|||
import android.widget.ImageButton;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.binary.BinaryMapIndexReader;
|
||||
import net.osmand.core.android.AtlasMapRendererView;
|
||||
import net.osmand.core.jni.Amenity;
|
||||
import net.osmand.core.jni.AmenitySymbolsProvider.AmenitySymbolsGroup;
|
||||
import net.osmand.core.jni.AreaI;
|
||||
import net.osmand.core.jni.IBillboardMapSymbol;
|
||||
|
@ -59,14 +59,19 @@ import net.osmand.core.jni.Utilities;
|
|||
import net.osmand.core.samples.android.sample1.MultiTouchSupport.MultiTouchZoomListener;
|
||||
import net.osmand.core.samples.android.sample1.data.PointDescription;
|
||||
import net.osmand.core.samples.android.sample1.mapcontextmenu.MapContextMenu;
|
||||
import net.osmand.core.samples.android.sample1.mapcontextmenu.MapMultiSelectionMenu;
|
||||
import net.osmand.core.samples.android.sample1.mapcontextmenu.MenuController;
|
||||
import net.osmand.core.samples.android.sample1.search.QuickSearchDialogFragment;
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.QuadRect;
|
||||
import net.osmand.data.RotatedTileBox;
|
||||
import net.osmand.osm.PoiCategory;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
private static final String TAG = "OsmAndCoreSample";
|
||||
|
@ -98,7 +103,6 @@ public class MainActivity extends AppCompatActivity {
|
|||
private MultiTouchSupport multiTouchSupport;
|
||||
|
||||
private MapContextMenu menu;
|
||||
private MapMultiSelectionMenu multiMenu;
|
||||
|
||||
// Context pin marker
|
||||
private MapMarkersCollection contextPinMarkersCollection;
|
||||
|
@ -259,7 +263,6 @@ public class MainActivity extends AppCompatActivity {
|
|||
|
||||
menu = new MapContextMenu();
|
||||
menu.setMainActivity(this);
|
||||
multiMenu = new MapMultiSelectionMenu(this);
|
||||
|
||||
if (!InstallOsmandAppDialog.show(getSupportFragmentManager(), this)
|
||||
&& externalStoragePermissionGranted) {
|
||||
|
@ -377,8 +380,8 @@ public class MainActivity extends AppCompatActivity {
|
|||
public boolean showContextMenu(@NonNull LatLon latLon,
|
||||
@Nullable PointDescription pointDescription,
|
||||
@Nullable Object object) {
|
||||
if (multiMenu.isVisible()) {
|
||||
multiMenu.hide();
|
||||
if (menu.getMultiSelectionMenu().isVisible()) {
|
||||
menu.getMultiSelectionMenu().hide();
|
||||
}
|
||||
if (!getBox().containsLatLon(latLon)) {
|
||||
menu.setMapCenter(latLon);
|
||||
|
@ -388,6 +391,16 @@ public class MainActivity extends AppCompatActivity {
|
|||
return true;
|
||||
}
|
||||
|
||||
private void showContextMenuForSelectedObjects(final LatLon latLon, final List<Object> selectedObjects) {
|
||||
menu.getMultiSelectionMenu().show(latLon, selectedObjects);
|
||||
}
|
||||
|
||||
private void hideMultiContextMenu() {
|
||||
if (menu.getMultiSelectionMenu().isVisible()) {
|
||||
menu.getMultiSelectionMenu().hide();
|
||||
}
|
||||
}
|
||||
|
||||
public RotatedTileBox getBox() {
|
||||
RotatedTileBox.RotatedTileBoxBuilder boxBuilder = new RotatedTileBox.RotatedTileBoxBuilder();
|
||||
LatLon screenCenter = getScreenCenter();
|
||||
|
@ -501,6 +514,8 @@ public class MainActivity extends AppCompatActivity {
|
|||
AreaI area = new AreaI(new PointI(touchPoint.getX() - delta, touchPoint.getY() - delta),
|
||||
new PointI(touchPoint.getX() + delta, touchPoint.getY() + delta));
|
||||
|
||||
List<Object> selectedObjects = new ArrayList<>();
|
||||
|
||||
MapSymbolInformationList symbolInfos = mapView.getSymbolsIn(area, false);
|
||||
for (int i = 0; i < symbolInfos.size(); i++) {
|
||||
MapSymbolInformation symbolInfo = symbolInfos.get(i);
|
||||
|
@ -529,55 +544,122 @@ public class MainActivity extends AppCompatActivity {
|
|||
}
|
||||
}
|
||||
|
||||
Log.e("111", i + ". lat=" + lat + " lon=" + lon);
|
||||
String name = null;
|
||||
MapMarker mapMarker;
|
||||
try {
|
||||
SymbolsGroup markerSymbolsGroup = SymbolsGroup.dynamic_cast(symbolInfo.getMapSymbol().getGroupPtr());
|
||||
mapMarker = markerSymbolsGroup.getMapMarker();
|
||||
Log.e("111", "marker=" + mapMarker.getMarkerId());
|
||||
} catch (Exception eMapMarker) {
|
||||
mapMarker = null;
|
||||
}
|
||||
if (mapMarker != null && mapMarker.getMarkerId() == CONTEXT_MARKER_ID) {
|
||||
// todo
|
||||
hideMultiContextMenu();
|
||||
menu.show();
|
||||
return true;
|
||||
} else {
|
||||
Amenity amenity;
|
||||
net.osmand.core.jni.Amenity amenity;
|
||||
try {
|
||||
AmenitySymbolsGroup amenitySymbolGroup = AmenitySymbolsGroup.dynamic_cast(symbolInfo.getMapSymbol().getGroupPtr());
|
||||
AmenitySymbolsGroup amenitySymbolGroup =
|
||||
AmenitySymbolsGroup.dynamic_cast(symbolInfo.getMapSymbol().getGroupPtr());
|
||||
amenity = amenitySymbolGroup.getAmenity();
|
||||
} catch (Exception eAmenity) {
|
||||
amenity = null;
|
||||
}
|
||||
if (amenity != null) {
|
||||
amenity.getId(); // todo
|
||||
Log.e("111", "amenity=" + amenity.getNativeName());
|
||||
name = amenity.getNativeName();
|
||||
net.osmand.core.jni.LatLon aLatLon = Utilities.convert31ToLatLon(amenity.getPosition31());
|
||||
Amenity osmandAmenity = findAmenity(amenity.getId().getId().longValue() >> 7,
|
||||
aLatLon.getLatitude(), aLatLon.getLongitude());
|
||||
if (osmandAmenity != null) {
|
||||
if (!selectedObjects.contains(osmandAmenity)) {
|
||||
selectedObjects.add(osmandAmenity);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
MapObject mapObject;
|
||||
try {
|
||||
MapObjectSymbolsGroup objSymbolGroup = MapObjectSymbolsGroup.dynamic_cast(symbolInfo.getMapSymbol().getGroupPtr());
|
||||
MapObjectSymbolsGroup objSymbolGroup =
|
||||
MapObjectSymbolsGroup.dynamic_cast(symbolInfo.getMapSymbol().getGroupPtr());
|
||||
mapObject = objSymbolGroup.getMapObject();
|
||||
} catch (Exception eMapObject) {
|
||||
mapObject = null;
|
||||
}
|
||||
ObfMapObject obfMapObject;
|
||||
if (mapObject != null) {
|
||||
Log.e("111", "mapObject=" + mapObject.getCaptionInNativeLanguage());
|
||||
name = mapObject.getCaptionInNativeLanguage();
|
||||
try {
|
||||
obfMapObject = ObfMapObject.dynamic_pointer_cast(mapObject);
|
||||
} catch (Exception eObfMapObject) {
|
||||
obfMapObject = null;
|
||||
}
|
||||
if (obfMapObject != null) {
|
||||
Log.e("111", "obfMapObject=" + obfMapObject.getId().getOsmId());
|
||||
obfMapObject.getId(); // todo
|
||||
name = obfMapObject.getCaptionInNativeLanguage();
|
||||
Amenity osmandAmenity = findAmenity(
|
||||
obfMapObject.getId().getId().longValue() >> 7, lat, lon);
|
||||
if (osmandAmenity != null) {
|
||||
if (!selectedObjects.contains(osmandAmenity)) {
|
||||
selectedObjects.add(osmandAmenity);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (name != null && name.trim().length() > 0) {
|
||||
selectedObjects.add(new PointDescription("", name));
|
||||
} else {
|
||||
selectedObjects.add(new PointDescription(lat, lon));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedObjects.size() == 1) {
|
||||
Object selectedObj = selectedObjects.get(0);
|
||||
LatLon latLon = new LatLon(lat, lon); //MenuController.getObjectLocation(selectedObj);
|
||||
PointDescription pointDescription = MenuController.getObjectName(selectedObj);
|
||||
//if (latLon == null) {
|
||||
// latLon = new LatLon(lat, lon);
|
||||
//}
|
||||
showContextMenu(latLon, pointDescription, selectedObj);
|
||||
return true;
|
||||
|
||||
} else if (selectedObjects.size() > 1) {
|
||||
showContextMenuForSelectedObjects(new LatLon(lat, lon), selectedObjects);
|
||||
return true;
|
||||
}
|
||||
|
||||
hideMultiContextMenu();
|
||||
hideContextMenu();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private Amenity findAmenity(long id, double lat, double lon) {
|
||||
QuadRect rect = MapUtils.calculateLatLonBbox(lat, lon, 50);
|
||||
List<Amenity> amenities = getMyApplication().getResourceManager().searchAmenities(
|
||||
new BinaryMapIndexReader.SearchPoiTypeFilter() {
|
||||
@Override
|
||||
public boolean accept(PoiCategory type, String subcategory) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return false;
|
||||
}
|
||||
}, rect.top, rect.left, rect.bottom, rect.right, -1, null);
|
||||
|
||||
Amenity res = null;
|
||||
for (Amenity amenity : amenities) {
|
||||
Long amenityId = amenity.getId() >> 1;
|
||||
if (amenityId == id) {
|
||||
res = amenity;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -17,6 +17,7 @@ import net.osmand.core.jni.LogSeverityLevel;
|
|||
import net.osmand.core.jni.Logger;
|
||||
import net.osmand.core.samples.android.sample1.SampleFormatter.MetricsConstants;
|
||||
import net.osmand.core.samples.android.sample1.SampleFormatter.SpeedConstants;
|
||||
import net.osmand.core.samples.android.sample1.resources.ResourceManager;
|
||||
import net.osmand.core.samples.android.sample1.search.QuickSearchHelper;
|
||||
import net.osmand.map.OsmandRegions;
|
||||
import net.osmand.map.WorldRegion;
|
||||
|
@ -48,6 +49,7 @@ public class SampleApplication extends Application {
|
|||
private QuickSearchHelper searchUICore;
|
||||
private GeocodingLookupService geocodingLookupService;
|
||||
private OsmandRegions regions;
|
||||
private ResourceManager resourceManager;
|
||||
|
||||
public static String LANGUAGE;
|
||||
public static boolean TRANSLITERATE = false;
|
||||
|
@ -67,6 +69,7 @@ public class SampleApplication extends Application {
|
|||
locationProvider = new SampleLocationProvider(this);
|
||||
searchUICore = new QuickSearchHelper(this);
|
||||
geocodingLookupService = new GeocodingLookupService(this);
|
||||
resourceManager = new ResourceManager(this);
|
||||
regions = new OsmandRegions();
|
||||
updateRegionVars();
|
||||
indexRegionsBoundaries();
|
||||
|
@ -136,6 +139,10 @@ public class SampleApplication extends Application {
|
|||
}
|
||||
}
|
||||
|
||||
public ResourceManager getResourceManager() {
|
||||
return resourceManager;
|
||||
}
|
||||
|
||||
public OsmandRegions getRegions() {
|
||||
return regions;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
package net.osmand.core.samples.android.sample1.resources;
|
||||
|
||||
import net.osmand.Location;
|
||||
import net.osmand.ResultMatcher;
|
||||
import net.osmand.binary.BinaryMapIndexReader.SearchPoiTypeFilter;
|
||||
import net.osmand.data.Amenity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface AmenityIndexRepository {
|
||||
|
||||
public void close();
|
||||
|
||||
public boolean checkContains(double latitude, double longitude);
|
||||
|
||||
public boolean checkContainsInt(int top31, int left31, int bottom31, int right31);
|
||||
|
||||
/**
|
||||
* Search amenities in the specified box doesn't cache results
|
||||
*/
|
||||
List<Amenity> searchAmenities(int stop, int sleft, int sbottom, int sright, int zoom, SearchPoiTypeFilter filter,
|
||||
ResultMatcher<Amenity> matcher);
|
||||
|
||||
List<Amenity> searchAmenitiesOnThePath(List<Location> locations, double radius, SearchPoiTypeFilter filter,
|
||||
ResultMatcher<Amenity> matcher);
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
package net.osmand.core.samples.android.sample1.resources;
|
||||
|
||||
|
||||
import net.osmand.Location;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.ResultMatcher;
|
||||
import net.osmand.binary.BinaryMapIndexReader;
|
||||
import net.osmand.binary.BinaryMapIndexReader.MapIndex;
|
||||
import net.osmand.binary.BinaryMapIndexReader.SearchPoiTypeFilter;
|
||||
import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.osm.PoiCategory;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class AmenityIndexRepositoryBinary implements AmenityIndexRepository {
|
||||
|
||||
private final static Log log = PlatformUtil.getLog(AmenityIndexRepositoryBinary.class);
|
||||
private final BinaryMapIndexReader index;
|
||||
|
||||
public AmenityIndexRepositoryBinary(BinaryMapIndexReader index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
try {
|
||||
index.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkContains(double latitude, double longitude) {
|
||||
int x31 = MapUtils.get31TileNumberX(longitude);
|
||||
int y31 = MapUtils.get31TileNumberY(latitude);
|
||||
return index.containsPoiData(x31, y31, x31, y31);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkContainsInt(int top31, int left31, int bottom31, int right31) {
|
||||
return index.containsPoiData(left31, top31, right31, bottom31);
|
||||
}
|
||||
|
||||
|
||||
public synchronized Map<PoiCategory, List<String>> searchAmenityCategoriesByName(String query, Map<PoiCategory, List<String>> map) {
|
||||
try {
|
||||
return index.searchPoiCategoriesByName(query, map);
|
||||
} catch (IOException e) {
|
||||
log.error("Error searching amenities", e); //$NON-NLS-1$
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
public synchronized List<Amenity> searchAmenitiesByName(int x, int y, int l, int t, int r, int b, String query, ResultMatcher<Amenity> resulMatcher) {
|
||||
long now = System.currentTimeMillis();
|
||||
List<Amenity> amenities = Collections.emptyList();
|
||||
SearchRequest<Amenity> req = BinaryMapIndexReader.buildSearchPoiRequest(x, y, query, l, r, t, b,resulMatcher);
|
||||
try {
|
||||
amenities = index.searchPoiByName(req);
|
||||
if (log.isDebugEnabled()) {
|
||||
String nm = "";
|
||||
List<MapIndex> mi = index.getMapIndexes();
|
||||
if(mi.size() > 0) {
|
||||
nm = mi.get(0).getName();
|
||||
}
|
||||
log.debug(String.format("Search for %s done in %s ms found %s (%s) %s.", //$NON-NLS-1$
|
||||
query, System.currentTimeMillis() - now, amenities.size(), nm, index.getFile().getName())); //$NON-NLS-1$
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("Error searching amenities", e); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
return amenities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<Amenity> searchAmenities(int stop, int sleft, int sbottom, int sright, int zoom,
|
||||
final SearchPoiTypeFilter filter, ResultMatcher<Amenity> matcher) {
|
||||
long now = System.currentTimeMillis();
|
||||
SearchRequest<Amenity> req = BinaryMapIndexReader.buildSearchPoiRequest(sleft, sright, stop, sbottom, zoom,
|
||||
filter, matcher);
|
||||
List<Amenity> result = null;
|
||||
try {
|
||||
result = index.searchPoi(req);
|
||||
} catch (IOException e) {
|
||||
log.error("Error searching amenities", e); //$NON-NLS-1$
|
||||
}
|
||||
if (log.isDebugEnabled() && result != null) {
|
||||
log.debug(String.format("Search for %s done in %s ms found %s.", //$NON-NLS-1$
|
||||
MapUtils.get31LatitudeY(stop) + " " + MapUtils.get31LongitudeX(sleft), System.currentTimeMillis() - now, result.size())); //$NON-NLS-1$
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<Amenity> searchAmenitiesOnThePath(List<Location> locations, double radius, final SearchPoiTypeFilter filter, ResultMatcher<Amenity> matcher) {
|
||||
long now = System.currentTimeMillis();
|
||||
List<Amenity> result = null;
|
||||
SearchRequest<Amenity> req = BinaryMapIndexReader.buildSearchPoiRequest(locations, radius,
|
||||
filter, matcher );
|
||||
try {
|
||||
result = index.searchPoi(req);
|
||||
} catch (IOException e) {
|
||||
log.error("Error searching amenities", e); //$NON-NLS-1$
|
||||
return result;
|
||||
}
|
||||
if (log.isDebugEnabled() && result != null) {
|
||||
log.debug(String.format("Search done in %s ms found %s.", (System.currentTimeMillis() - now), result.size())); //$NON-NLS-1$
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
package net.osmand.core.samples.android.sample1.resources;
|
||||
|
||||
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.ResultMatcher;
|
||||
import net.osmand.binary.BinaryMapIndexReader;
|
||||
import net.osmand.core.samples.android.sample1.SampleApplication;
|
||||
import net.osmand.core.samples.android.sample1.SampleUtils;
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class ResourceManager {
|
||||
|
||||
private final SampleApplication app;
|
||||
private final Map<String, AmenityIndexRepository> amenityRepositories = new ConcurrentHashMap<>();
|
||||
|
||||
public ResourceManager(SampleApplication app) {
|
||||
this.app = app;
|
||||
setRepositories();
|
||||
}
|
||||
|
||||
private void setRepositories() {
|
||||
ArrayList<File> files = new ArrayList<>();
|
||||
File appPath = app.getAppPath(null);
|
||||
SampleUtils.collectFiles(appPath, IndexConstants.BINARY_MAP_INDEX_EXT, files);
|
||||
SampleUtils.collectFiles(app.getAppPath(IndexConstants.WIKI_INDEX_DIR), IndexConstants.BINARY_MAP_INDEX_EXT, files);
|
||||
|
||||
for (File f : files) {
|
||||
try {
|
||||
RandomAccessFile mf = new RandomAccessFile(f.getPath(), "r");
|
||||
BinaryMapIndexReader reader = new BinaryMapIndexReader(mf, f);
|
||||
if (reader.containsPoiData()) {
|
||||
amenityRepositories.put(f.getName(), new AmenityIndexRepositoryBinary(reader));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<Amenity> searchAmenities(BinaryMapIndexReader.SearchPoiTypeFilter filter,
|
||||
double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, final ResultMatcher<Amenity> matcher) {
|
||||
final List<Amenity> amenities = new ArrayList<>();
|
||||
try {
|
||||
if (!filter.isEmpty()) {
|
||||
int top31 = MapUtils.get31TileNumberY(topLatitude);
|
||||
int left31 = MapUtils.get31TileNumberX(leftLongitude);
|
||||
int bottom31 = MapUtils.get31TileNumberY(bottomLatitude);
|
||||
int right31 = MapUtils.get31TileNumberX(rightLongitude);
|
||||
for (AmenityIndexRepository index : amenityRepositories.values()) {
|
||||
if (matcher != null && matcher.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
if (index.checkContainsInt(top31, left31, bottom31, right31)) {
|
||||
List<Amenity> r = index.searchAmenities(top31,
|
||||
left31, bottom31, right31, zoom, filter, matcher);
|
||||
if(r != null) {
|
||||
amenities.addAll(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return amenities;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue