[Samples] added tap on map feature

This commit is contained in:
Alexey Kulish 2016-11-20 15:33:33 +03:00
parent fac27c2d29
commit 019638b4fa
6 changed files with 335 additions and 20 deletions

View file

@ -28,9 +28,8 @@
<item name="expandable_list_background">@color/list_item_light</item> <item name="expandable_list_background">@color/list_item_light</item>
<item name="osmo_header_background">@color/osmo_header_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_subheader_text_color">@color/dashboard_subheader_text_light</item>
<item name="dashboard_general_button_text_color"> <item name="dashboard_general_button_text_color">@color/dashboard_general_button_text_light</item>
@color/dashboard_general_button_text_light <item name="expandable_list_item_background">@drawable/expandable_list_item_background_light</item>
</item>
<item name="android:textColorPrimary">@color/color_black</item> <item name="android:textColorPrimary">@color/color_black</item>
<item name="spinnerItemTextColor">@color/color_black</item> <item name="spinnerItemTextColor">@color/color_black</item>
<item name="spinnerListBackground">@color/spinner_list_background_light</item> <item name="spinnerListBackground">@color/spinner_list_background_light</item>

View file

@ -25,8 +25,8 @@ import android.view.View;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.TextView; import android.widget.TextView;
import net.osmand.binary.BinaryMapIndexReader;
import net.osmand.core.android.AtlasMapRendererView; import net.osmand.core.android.AtlasMapRendererView;
import net.osmand.core.jni.Amenity;
import net.osmand.core.jni.AmenitySymbolsProvider.AmenitySymbolsGroup; import net.osmand.core.jni.AmenitySymbolsProvider.AmenitySymbolsGroup;
import net.osmand.core.jni.AreaI; import net.osmand.core.jni.AreaI;
import net.osmand.core.jni.IBillboardMapSymbol; 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.MultiTouchSupport.MultiTouchZoomListener;
import net.osmand.core.samples.android.sample1.data.PointDescription; 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.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.core.samples.android.sample1.search.QuickSearchDialogFragment;
import net.osmand.data.Amenity;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.data.QuadRect;
import net.osmand.data.RotatedTileBox; import net.osmand.data.RotatedTileBox;
import net.osmand.osm.PoiCategory;
import net.osmand.util.MapUtils; import net.osmand.util.MapUtils;
import java.io.File; import java.io.File;
import java.io.FilenameFilter; import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity { public class MainActivity extends AppCompatActivity {
private static final String TAG = "OsmAndCoreSample"; private static final String TAG = "OsmAndCoreSample";
@ -98,7 +103,6 @@ public class MainActivity extends AppCompatActivity {
private MultiTouchSupport multiTouchSupport; private MultiTouchSupport multiTouchSupport;
private MapContextMenu menu; private MapContextMenu menu;
private MapMultiSelectionMenu multiMenu;
// Context pin marker // Context pin marker
private MapMarkersCollection contextPinMarkersCollection; private MapMarkersCollection contextPinMarkersCollection;
@ -259,7 +263,6 @@ public class MainActivity extends AppCompatActivity {
menu = new MapContextMenu(); menu = new MapContextMenu();
menu.setMainActivity(this); menu.setMainActivity(this);
multiMenu = new MapMultiSelectionMenu(this);
if (!InstallOsmandAppDialog.show(getSupportFragmentManager(), this) if (!InstallOsmandAppDialog.show(getSupportFragmentManager(), this)
&& externalStoragePermissionGranted) { && externalStoragePermissionGranted) {
@ -377,8 +380,8 @@ public class MainActivity extends AppCompatActivity {
public boolean showContextMenu(@NonNull LatLon latLon, public boolean showContextMenu(@NonNull LatLon latLon,
@Nullable PointDescription pointDescription, @Nullable PointDescription pointDescription,
@Nullable Object object) { @Nullable Object object) {
if (multiMenu.isVisible()) { if (menu.getMultiSelectionMenu().isVisible()) {
multiMenu.hide(); menu.getMultiSelectionMenu().hide();
} }
if (!getBox().containsLatLon(latLon)) { if (!getBox().containsLatLon(latLon)) {
menu.setMapCenter(latLon); menu.setMapCenter(latLon);
@ -388,6 +391,16 @@ public class MainActivity extends AppCompatActivity {
return true; 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() { public RotatedTileBox getBox() {
RotatedTileBox.RotatedTileBoxBuilder boxBuilder = new RotatedTileBox.RotatedTileBoxBuilder(); RotatedTileBox.RotatedTileBoxBuilder boxBuilder = new RotatedTileBox.RotatedTileBoxBuilder();
LatLon screenCenter = getScreenCenter(); LatLon screenCenter = getScreenCenter();
@ -501,6 +514,8 @@ public class MainActivity extends AppCompatActivity {
AreaI area = new AreaI(new PointI(touchPoint.getX() - delta, touchPoint.getY() - delta), AreaI area = new AreaI(new PointI(touchPoint.getX() - delta, touchPoint.getY() - delta),
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); MapSymbolInformationList symbolInfos = mapView.getSymbolsIn(area, false);
for (int i = 0; i < symbolInfos.size(); i++) { for (int i = 0; i < symbolInfos.size(); i++) {
MapSymbolInformation symbolInfo = symbolInfos.get(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; MapMarker mapMarker;
try { try {
SymbolsGroup markerSymbolsGroup = SymbolsGroup.dynamic_cast(symbolInfo.getMapSymbol().getGroupPtr()); SymbolsGroup markerSymbolsGroup = SymbolsGroup.dynamic_cast(symbolInfo.getMapSymbol().getGroupPtr());
mapMarker = markerSymbolsGroup.getMapMarker(); mapMarker = markerSymbolsGroup.getMapMarker();
Log.e("111", "marker=" + mapMarker.getMarkerId());
} catch (Exception eMapMarker) { } catch (Exception eMapMarker) {
mapMarker = null; mapMarker = null;
} }
if (mapMarker != null && mapMarker.getMarkerId() == CONTEXT_MARKER_ID) { if (mapMarker != null && mapMarker.getMarkerId() == CONTEXT_MARKER_ID) {
// todo hideMultiContextMenu();
menu.show();
return true;
} else { } else {
Amenity amenity; net.osmand.core.jni.Amenity amenity;
try { try {
AmenitySymbolsGroup amenitySymbolGroup = AmenitySymbolsGroup.dynamic_cast(symbolInfo.getMapSymbol().getGroupPtr()); AmenitySymbolsGroup amenitySymbolGroup =
AmenitySymbolsGroup.dynamic_cast(symbolInfo.getMapSymbol().getGroupPtr());
amenity = amenitySymbolGroup.getAmenity(); amenity = amenitySymbolGroup.getAmenity();
} catch (Exception eAmenity) { } catch (Exception eAmenity) {
amenity = null; amenity = null;
} }
if (amenity != null) { if (amenity != null) {
amenity.getId(); // todo name = amenity.getNativeName();
Log.e("111", "amenity=" + 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 { } else {
MapObject mapObject; MapObject mapObject;
try { try {
MapObjectSymbolsGroup objSymbolGroup = MapObjectSymbolsGroup.dynamic_cast(symbolInfo.getMapSymbol().getGroupPtr()); MapObjectSymbolsGroup objSymbolGroup =
MapObjectSymbolsGroup.dynamic_cast(symbolInfo.getMapSymbol().getGroupPtr());
mapObject = objSymbolGroup.getMapObject(); mapObject = objSymbolGroup.getMapObject();
} catch (Exception eMapObject) { } catch (Exception eMapObject) {
mapObject = null; mapObject = null;
} }
ObfMapObject obfMapObject; ObfMapObject obfMapObject;
if (mapObject != null) { if (mapObject != null) {
Log.e("111", "mapObject=" + mapObject.getCaptionInNativeLanguage()); name = mapObject.getCaptionInNativeLanguage();
try { try {
obfMapObject = ObfMapObject.dynamic_pointer_cast(mapObject); obfMapObject = ObfMapObject.dynamic_pointer_cast(mapObject);
} catch (Exception eObfMapObject) { } catch (Exception eObfMapObject) {
obfMapObject = null; obfMapObject = null;
} }
if (obfMapObject != null) { if (obfMapObject != null) {
Log.e("111", "obfMapObject=" + obfMapObject.getId().getOsmId()); name = obfMapObject.getCaptionInNativeLanguage();
obfMapObject.getId(); // todo 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; 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 @Override

View file

@ -17,6 +17,7 @@ import net.osmand.core.jni.LogSeverityLevel;
import net.osmand.core.jni.Logger; import net.osmand.core.jni.Logger;
import net.osmand.core.samples.android.sample1.SampleFormatter.MetricsConstants; 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.SampleFormatter.SpeedConstants;
import net.osmand.core.samples.android.sample1.resources.ResourceManager;
import net.osmand.core.samples.android.sample1.search.QuickSearchHelper; import net.osmand.core.samples.android.sample1.search.QuickSearchHelper;
import net.osmand.map.OsmandRegions; import net.osmand.map.OsmandRegions;
import net.osmand.map.WorldRegion; import net.osmand.map.WorldRegion;
@ -48,6 +49,7 @@ public class SampleApplication extends Application {
private QuickSearchHelper searchUICore; private QuickSearchHelper searchUICore;
private GeocodingLookupService geocodingLookupService; private GeocodingLookupService geocodingLookupService;
private OsmandRegions regions; private OsmandRegions regions;
private ResourceManager resourceManager;
public static String LANGUAGE; public static String LANGUAGE;
public static boolean TRANSLITERATE = false; public static boolean TRANSLITERATE = false;
@ -67,6 +69,7 @@ public class SampleApplication extends Application {
locationProvider = new SampleLocationProvider(this); locationProvider = new SampleLocationProvider(this);
searchUICore = new QuickSearchHelper(this); searchUICore = new QuickSearchHelper(this);
geocodingLookupService = new GeocodingLookupService(this); geocodingLookupService = new GeocodingLookupService(this);
resourceManager = new ResourceManager(this);
regions = new OsmandRegions(); regions = new OsmandRegions();
updateRegionVars(); updateRegionVars();
indexRegionsBoundaries(); indexRegionsBoundaries();
@ -136,6 +139,10 @@ public class SampleApplication extends Application {
} }
} }
public ResourceManager getResourceManager() {
return resourceManager;
}
public OsmandRegions getRegions() { public OsmandRegions getRegions() {
return regions; return regions;
} }

View file

@ -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);
}

View file

@ -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;
}
}

View file

@ -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;
}
}