Skip to content

Commit

Permalink
Merge pull request #63 from heremaps/esd/978
Browse files Browse the repository at this point in the history
ESD-978: Update example apps for release 4.6.3.0
  • Loading branch information
datasun authored Feb 18, 2021
2 parents 01ae103 + c6b8219 commit bf35d3a
Show file tree
Hide file tree
Showing 297 changed files with 318 additions and 356 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ For an overview of the existing features, please check the _Developer's Guide_ f

> For now, the _Navigate Edition_ is only available upon request. Please contact your HERE representative to receive access including a set of evaluation credentials.
## List of Available Example Apps (Version 4.6.2.0)
## List of Available Example Apps (Version 4.6.3.0)
In this repository you can find the [latest example apps](examples/latest) that show key features of the HERE SDK in ready-to-use applications:

- **HelloMap**: Shows the classic 'Hello World'.
Expand All @@ -42,7 +42,7 @@ In this repository you can find the [latest example apps](examples/latest) that
- **Positioning**: Shows how to integrate HERE Positioning. Exclusively available for the _Navigate Edition_.
- **Traffic**: Shows how to search for real-time traffic and how to visualize it on the map.
- **StandAloneEngine**: Shows how to use an engine without a map view.
- **Venues**: Shows how to integrate private venues. Exclusively available for the _Navigate Edition_.
- **IndoorMap**: Shows how to integrate private venues. Exclusively available for the _Navigate Edition_.
- **UnitTesting**: Shows how to mock HERE SDK classes when writing unit tests (Android only, the example app is available for the _Explore Edition_ and the _Navigate Edition_).

Most example apps contain a class named "XY-Example" where XY stands for the feature, which is in most cases equal to the name of the app. If you are looking for example code that shows how to use a certain HERE SDK feature, then please look for this class as it contains the most interesting parts. Note that the overall app architecture is kept as simple as possible to not shadow the parts in focus.
Expand All @@ -55,8 +55,8 @@ Find the [latest examples](examples/latest) for the edition and platform of your
- Examples for the HERE SDK for iOS ([Lite Edition](examples/latest/lite/ios/), [Explore Edition](examples/latest/explore/ios/), [Navigate Edition](examples/latest/navigate/ios/))
- Examples for the HERE SDK for Flutter ([Explore Edition](examples/latest/explore/flutter/), [Navigate Edition](examples/latest/navigate/flutter/))

## Example Apps for Other Versions
In addition to the apps above, this repo also contains example apps for [other HERE SDK versions](examples/other_releases): Here you can find older releases _or_ releases that are not yet public on [developer.here.com](https://developer.here.com/).
## Example Apps for Older Versions
Above you can find the example app links for the _latest_ HERE SDK version. If you are looking for an older version, please check our [release page](https://github.com/heremaps/here-sdk-examples/releases) where you can download tagged older releases.

## What You Need to Execute the Example Apps
1. Acquire a set of credentials by registering yourself on [developer.here.com](https://developer.here.com/) - or ask your HERE representative.
Expand Down
2 changes: 1 addition & 1 deletion examples/latest/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
This folder contains the HERE SDK examples apps for version: 4.6.2.0
This folder contains the HERE SDK examples apps for version: 4.6.3.0

- HERE SDK for Android ([Lite Edition](lite/android/), [Explore Edition](explore/android/), [Navigate Edition](navigate/android/))
- HERE SDK for iOS ([Lite Edition](lite/ios/), [Explore Edition](explore/ios/), [Navigate Edition](navigate/ios/))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
The Venues example app shows how to display private venues on a map view and how to interact with them. Venues are tied to your credentials. Talk to your HERE representative to provide your venue data and enable your venue data on the map. By default, no venues are shown on the map, but you can enable your private venues for your set of credentials.
The Indoor Map example app shows how to display private venues on a map view and how to interact with them. Venues are tied to your credentials. Talk to your HERE representative to provide your venue data and enable your venue data on the map. By default, no venues are shown on the map, but you can enable your private venues for your set of credentials.

Build instructions:
-------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
import java.util.List;
import java.util.Locale;

// Provides UI elements for indoor route calculation and displays an indoor route on the map.
public class IndoorRoutingUIController implements LongPressListener {
private static final String TAG = IndoorRoutingUIController.class.getSimpleName();
private VenueMap venueMap;
Expand Down Expand Up @@ -83,9 +84,15 @@ public IndoorRoutingUIController(
this.venueMap = venueEngine.getVenueMap();
this.mapView = mapView;
context = indoorRoutingLayout.getContext();
mapView.getGestures().setLongPressListener(this);

// Initialize IndoorRoutingEngine to be able to calculate indoor routes.
engine = new IndoorRoutingEngine(venueEngine.getVenueService());
// Initialize IndoorRoutingController to be able to display indoor routes on the map.
controller = new IndoorRoutingController(venueMap, mapView.getMapScene());
// Set a long press listener.
mapView.getGestures().setLongPressListener(this);

// Get end setup needed UI elements.
this.indoorRoutingLayout = indoorRoutingLayout;
indoorRoutingButton.setOnClickListener(v -> setVisible(!visible));
indoorRoutingSettings = indoorRoutingLayout.findViewById(R.id.indoorRouteSettingsLayout);
Expand Down Expand Up @@ -120,22 +127,35 @@ public IndoorRoutingUIController(
.setOnClickListener(this ::onAvoidFeatureChanged);
}

// Hide UI elements for indoor routes calculation.
setVisible(false);
// Hide UI elements for indoor route settings.
setSettingsVisible(false);
// Setup IndoorRouteStyle object.
setUpRouteStyle();
}

// Get visibility of UI elements for indoor routes calculation.
public boolean isVisible() {
return visible;
}

// Setup IndoorRouteStyle object, which will be used in indoor route rendering.
private void setUpRouteStyle() {
// Set start, end, walk and drive markers. The start marker will be shown at the start of
// the route and the destination marker at the destination of the route. The walk marker
// will be shown when the route switches from drive to walk mode and the drive marker
// vice versa.
Anchor2D middleBottomAnchor = new Anchor2D(0.5, 1.0);
routeStyle.setStartMarker(initMapMarker(R.drawable.ic_route_start, middleBottomAnchor));
routeStyle.setDestinationMarker(initMapMarker(R.drawable.ic_route_end, middleBottomAnchor));
routeStyle.setWalkMarker(initMapMarker(R.drawable.indoor_walk));
routeStyle.setDriveMarker(initMapMarker(R.drawable.indoor_drive));

// Set markers for some of the indoor features. The 'up' marker indicates that the route
// is going up, and the 'down' marker indicates that the route is going down. The default
// marker indicates that a user should exit the current indoor feature (e.g. an elevator)
// to enter the current floor.
IndoorFeatures[] features = new IndoorFeatures[] {IndoorFeatures.ELEVATOR,
IndoorFeatures.ESCALATOR,
IndoorFeatures.STAIRS,
Expand All @@ -148,6 +168,7 @@ private void setUpRouteStyle() {
}
}

// Creates a marker with a resource ID of an image and an anchor.
private @Nullable MapMarker initMapMarker(final int resourceID, final Anchor2D anchor) {
if (resourceID == 0) {
return null;
Expand All @@ -160,6 +181,9 @@ private void setUpRouteStyle() {
return null;
}

// Gets a resource ID of an image based on the indoor feature and delta Z, where 0 means
// a standard icon, 1 means that the icon shows that route is going up, and -1 that it is
// going down.
private int getIndoorFeatureResource(IndoorFeatures feature, int delta_z) {
switch (feature) {
case ELEVATOR:
Expand Down Expand Up @@ -214,6 +238,7 @@ private int getIndoorFeatureResource(IndoorFeatures feature, int delta_z) {
return initMapMarker(resourceID, new Anchor2D());
}

// Set visibility of UI elements for indoor routes calculation.
private void setVisible(final boolean value) {
if (visible == value) {
return;
Expand All @@ -222,6 +247,7 @@ private void setVisible(final boolean value) {
indoorRoutingLayout.setVisibility(visible ? View.VISIBLE : View.GONE);
}

// Set visibility of UI elements for indoor routes settings.
private void setSettingsVisible(final boolean value) {
if (settingsVisible == value) {
return;
Expand All @@ -230,31 +256,39 @@ private void setSettingsVisible(final boolean value) {
indoorRoutingSettings.setVisibility(settingsVisible ? View.VISIBLE : View.GONE);
}

// Create an indoor waypoint based on the tap point on the map.
private @Nullable IndoorWaypoint getIndoorWaypoint(@NonNull final Point2D origin) {
GeoCoordinates position = mapView.viewToGeoCoordinates(origin);
if (position != null) {
// Check if there is a venue in the tap position.
Venue venue = venueMap.getVenue(position);
if (venue != null) {
VenueModel venueModel = venue.getVenueModel();
Venue selectedVenue = venueMap.getSelectedVenue();
if (selectedVenue != null &&
venueModel.getId() == selectedVenue.getVenueModel().getId()) {
// If the venue is the selected one, return an indoor waypoint
// with indoor information.
return new IndoorWaypoint(
position,
String.valueOf(venueModel.getId()),
String.valueOf(venue.getSelectedLevel().getId()));
} else {
// If the venue is not the selected one, select it.
venueMap.setSelectedVenue(venue);
return null;
}
}

// If the tap position is outside of any venue, return an indoor waypoint with
// outdoor information.
return new IndoorWaypoint(position);
}

return null;
}

// Update the text view with a new indoor waypoint.
private void updateWaypointTextView(final TextView textView, final IndoorWaypoint waypoint) {
StringBuilder text = new StringBuilder();
if (waypoint.getVenueId() != null && waypoint.getLevelId() != null) {
Expand All @@ -273,43 +307,54 @@ private void updateWaypointTextView(final TextView textView, final IndoorWaypoin
textView.setText(text.toString());
}

public void onTap(@NonNull final Point2D origin) {
IndoorWaypoint waypoint = getIndoorWaypoint(origin);
if (visible && waypoint != null) {
destinationWaypoint = waypoint;
updateWaypointTextView(destinationTextView, waypoint);
}
}

// Handle the long press events.
@Override
public void onLongPress(@NonNull final GestureState state, @NonNull final Point2D origin) {
if (!visible || state != GestureState.END) {
return;
}
IndoorWaypoint waypoint = getIndoorWaypoint(origin);
if (waypoint != null) {
// Set a start waypoint.
startWaypoint = waypoint;
updateWaypointTextView(startTextView, waypoint);
}
}

// Handle the tap events.
public void onTap(@NonNull final Point2D origin) {
IndoorWaypoint waypoint = getIndoorWaypoint(origin);
if (visible && waypoint != null) {
// Set a destination waypoint.
destinationWaypoint = waypoint;
updateWaypointTextView(destinationTextView, waypoint);
}
}

// Calculate an indoor route based on the start and destination waypoints, and
// the indoor route options.
private void calculateRoute() {
engine.calculateRoute(startWaypoint, destinationWaypoint, routeOptions, this ::showRoute);
}

// Show the resulting route.
private void showRoute(
@Nullable final RoutingError routingError, @Nullable final List<Route> routeList) {
// Hide the existing route, if any.
controller.hideRoute();
if (routingError == null && routeList != null) {
Route route = routeList.get(0);
// Show the resulting route with predefined indoor routing styles.
controller.showRoute(route, routeStyle);
} else {
// Show a toast message in case of error.
Toast toast = Toast.makeText(
context, "Failed to calculate the indoor route!", Toast.LENGTH_LONG);
toast.show();
}
}

// Change optimization mode for the indoor route calculation.
private void onRouteModeChanged() {
if (fastRadioButton.isChecked()) {
routeOptions.routeOptions.optimizationMode = OptimizationMode.FASTEST;
Expand All @@ -318,6 +363,7 @@ private void onRouteModeChanged() {
}
}

// Change transport mode for the indoor route calculation.
private void onTransportModeChanged() {
if (pedestrianRadioButton.isChecked()) {
routeOptions.transportMode = IndoorTransportMode.PEDESTRIAN;
Expand All @@ -326,6 +372,7 @@ private void onTransportModeChanged() {
}
}

// Change walking speed for the indoor route calculation.
private boolean onWalkSpeedEditorAction(TextView textView, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_DONE ||
event != null && event.getAction() == KeyEvent.ACTION_DOWN &&
Expand Down Expand Up @@ -353,6 +400,7 @@ private boolean onWalkSpeedEditorAction(TextView textView, int actionId, KeyEven
return false;
}

// Adds or removes avoidance features for indoor route calculation.
private void onAvoidFeatureChanged(View view) {
CheckBox checkBox = (CheckBox) view;
if (checkBox == null) {
Expand All @@ -371,6 +419,7 @@ private void onAvoidFeatureChanged(View view) {
}
}

// Get an indoor feature based on the name.
private IndoorFeatures getIndoorFeature(String checkboxName) throws IllegalStateException {
switch (checkboxName) {
case "Elevator":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ private void onVenueEngineInitCompleted() {
venueSearchController = new VenueSearchController(venueMap, venueTapController,
findViewById(R.id.venueSearchLayout), findViewById(R.id.searchButton));

// Create a indoor routing controller
indoorRoutingController = new IndoorRoutingUIController(
venueEngine,
mapView,
Expand Down Expand Up @@ -254,8 +255,10 @@ private void setGoButtonEnabled(boolean value) {
// Tap listener for MapView
private final TapListener tapListener = origin -> {
if (indoorRoutingController.isVisible()) {
// In case if the indoor routing controller is visible, redirect the event to it.
indoorRoutingController.onTap(origin);
} else {
// Otherwise, redirect the event to the venue tap controller.
venueTapController.onTap(origin);
}
};
Expand All @@ -277,6 +280,7 @@ protected void onDestroy() {
super.onDestroy();
if (mapView != null) {
mapView.getGestures().setTapListener(null);
mapView.getGestures().setLongPressListener(null);
}
venueEngine.destroy();
mapView.onDestroy();
Expand Down
Loading

0 comments on commit bf35d3a

Please sign in to comment.