How to make a Custom Map Overlay Part II .. Show the user on the Map and a Custom Map Overlay

Part II Custom Map Overlay

.. Show the user on the Map and a Custom Map Overlay. Add map 'control' information to the Display.

How to Build this App

Part I to this tutorial explained how to make the Custom Map Overlay. This part explains ways to animate and do interesting things with the overlay using the Maps control's object Properties.

This is the map overlay playground experiments Designer.

The tutorial example app works in Android 4.2 - 8.1. It is built using only Blocks. Whether it works in higher operating system versions I do not know. Try the example aia.

How the Interface to the Overlay is Built

The example app is designed on a Tablet. The example aia will run on small cell phones too. For small screens you it may be necessary to adapt the location of some of the controls.

Developers use these App Inventor tools and should familiarize themselves with the documentation:

Housekeeping

  • Set the Scope in Screen1 Properties to Asset (to access Media compatible with App Inventor 2 nb187 and higher).

Use the Location Capabilities of the App

  • Show the user's location using a LocationSensor and the Map component. The code is in the Procedure setUpLocationSensor. The Procedure is called in the Screen1.Initialize Block.
    setupLocationSensor

The ShowUser Block provides an icon at the Android's current location( provided the device's Settings allow Location and the GPS is enabled).TravelDirection
Your location probably will not display in the example overlay area immediately but will display on an expanded Map (perhaps set the Zoom to a value of 2 or 3 to find out where you are in relation to the map overlay?

How to Animate (dynamically modify) the Objects in the Overlay

  • Affix a Title and Description to the pop up Infobox associated with each object. Use the Designer Property options or Blocks. When the object is touched an Infobox (a pop up) appears only if you check EnableInfobox in the component's Properties in the Designer or set enabled with Blocks. Enabling the ability to use the object's pop up can be set with Blocks. However in the tutorial example, enabling is set using the Designer Properties of each object. Basically, EnableInfobox is checked; FillColor is changed to what color you prefer and the component is given a Title and/or Description that will display in the Infobox .

  • POI's. You can assign CustomMarkers to your markers using the Markers in your overlay or add the Markers using the Designer. Points of Interest can be represented by a graphic. The parameters for the example (Marker1) are set in the control's Properties on the Designer but can be set in Blocks. The Any components Blocks can also set all the Markers you display in your overlay as CustomMarkers. Basic Pin Markers can change color. Some svg images can change color; png and jpg images cannot be color changed.

  • Multiple FeatureCollections are possible. Several overlays can coexist simultaneously. If you add a second FeatureCollection that contains some of the same objects you drew in another loaded overlay; those duplicate objects create coding issues. The issues can, with difficulty, be overcome. If you add a second FeatureCollection, ensure it does not contain previously drawn objects and avoid issues.

  • Change the Polygon, Marker or LineString object's color and otherwise manipulate objects with the Designer Map Properties for that object. The changes are made using the object's Properties on the Designer screen. Changes can be made using code.

  • Polygon.ShowInfobox and Polygon.HideInfobox are not working; a bug MIT has the Block on its to do list. Marker.ShowInfobox and Marker.HideInfobox work fine!

  • Add a building locator tool to the Screen. Either a ListView (or ListPicker) or a Button is used to change an object's color temporarily to help locate it on the map. The tools provides a toggle. Basically all objects except CustomMarker png or jpg files can be toggled with color. SVG file CustomMarkers do change color. A Marker Infobox can be controlled with Blocks. Unfortunately, at the moment, because of a bug, the ShowInfobox method is only working for Markers. Other map components do not.

  • Did you forget to include something in your overlay. Add additional features to the map from the Designer to the display independent of the FeatureCollection or revise the geojson overlay file.

  1. Drop a Marker, Polygon or LineString on the map. Modify the object in the Designer. A caution. Adding individual polygons is more difficult than using the web site tool to create them. It is possible and may be convenient to use the Designer to place Markers. Use the Designer to supplement the polygons and lines you placed with the geojson overlay as separate objects. See http://ai2.appinventor.mit.edu.ezproxy.canberra.edu.au/reference/components/maps.html .
  2. A relatively simple way to update your overlay is to load a previously created geojson (Open > File ) on the geojson web page; select the file and continue working on it. Save the modified FeatureCollection you just modified with a different name; then reload the geojson into Media.

How to use the example animation/navigation techniques

There are several basic animation types:

  • The Find/Using Buttons examples show how to blink or change the color of an overlay object. An object can be momentarily highlighted by changing its color using Buttons or a ListView in the example. Not all the objects on the map overlay are currently enabled to do this.
    theButtons
  1. Toggle Canteen - Button5. Changes the canteen color.

  2. Blink Canteen - Button8 . Use a Clock to blink.

  3. Toggle Theater - Button6. Provides an announcement of current play.

  4. Science - Button7. Changes color of the svg image.

  5. The ListView duplicates some of these capabilities and provides animation for additional components.

Press the Button or Click the ListView item associated with an overlay item to change its color; press again to revert to the original display.

  • Tools. Re-center the map overlay, hide and restore the overlay, create a List of Markers or Polygons in the FeatureCollection (useful if you need to change icons etc. of related items). and List of Markers and changing their icon.

theTools

  1. Center Map - Button1. Centers the map overlay.
  2. Clear Overlay - Button4 Hides the FeatureCollection (visible = false)
  3. Restore - Button9 Shows the FeatureCollection (visible = true)
  4. List of Polygons - Button2 Provides a warning message. The Navigate School Campus shows an application of the technique.
  5. List of Markers - Button3 Provides a warning message. Items 4 & 5 use this routine

How to use the Map Overlay Animation Demonstrations


campusDetail6.aia (18.1 KB)

Press the Button or Click the ListView item associated with an overlay item to change its color; press again to revert to the original display.

The animation features are not yet optimized (the example does not track which features an object is currently using) and using different types of modification (without reverting to the original) can result in confusion. Avoid this if you limit the way something can be done when coding your real app; the example shows various ways. You probably do not want to use all the techniques in an actual app.

A Clock is used to blink a Marker or a Polygon. Two examples are shown, each has its own Clock component (Toogle Canteen - ButtonB5 and Blink Canteen - Button8).

The aia containing all the experimental code is called campusDetail6.

=========================

Navigate School Campus

The Part II example is a compilation of techniques to manipulate the map overlay. The controls do not look very pretty. CampusExplore is the aia of a partially completed app using a map overlay. The technique can be used on a map of a school campus or park to help a visitor to find things. Keep the interface simple.
campusExplore.aia (16.0 KB)

Useful code while working with an advanced version of this app

How make a Procedure to strip the runtime names of the Markers from a FeatureControl .

A List of the Markers in the Project is useful while using an Any component Marker control.


When you import a Map Overlay FeatureCollection, all the components are colored Green. This is a routine to re- set the color of all the objects. setMarkerPolygonDefaultColor


How to set up the new ListView items available since the release of App Inventor 2 nb187. Use the new ListView.CreateElement Block as shown. There are probably other ways to fill the ListView items.

setUpLVfiles


gpsONOFF
Toggle the GPS off to view the campus overlay when your device is not near the campus.


What next?
This is an example, not a completed app. As a developer you can make this work the way you want it to. You can:

  • adapt the code using your own map overlay. :astonished:

  • use a similar map overlay to create a Pokémon-like game. Combine a Map with a CloudDB control perhaps. Use a routine to determine if the user is near a Marker or Polygon that has it's opacity set to a low value and resets opacity to a highly visible value when at a certain distance. 'Capture' that object if the user is within it's boundaries.

  • create a virtual geocaching app. Use Marker.DistanceToFeature or BearingToFeature or BearingToPoint to find the virtual geocache that is on the overlay map. Some ideas for geocaching in Texas.. This is a way to build a treasure hunt app.

  • add a function to calculate the straight-line distance between the app user and one or more of the FeatureCollection objects.

  • create a function to determine if the user has arrived at a map overlay 'destination'.

  • use small images as CustomMarkers to display photos of campus buildings, park features etc.

  • enable Map ShowZoom (to provide a + / - feature to zoom the map.

  • enable Map ShowScale to provide a distance scale on the map.

  • enable Map ShowCompass to provide a small compass but only on the most recent Android versions.

  • provide multiple map overlays

  • and add whatever your imagination and coding skills allow using only Blocks or using extensions.

Requirements for Part II

  • Either a WIFI or network connection to access the Internet to display the map and the user's location
  • gps hardware in the device
  • a LocationSensor component
  • no extensions required
  • intermediate to advanced App Inventor coding skills

Reality check:

  • Navigating inside a building. When your FeatureCollection polygons are inside a building your Android device GPS might not know where it is at while inside the building. Expect reduced gps Accuracy or the inability to achieve a satellite fix or trigger a LocationChanged even when inside a building unless the room has windows.

  • the Map control works using the server at OpenStreetMaps. This means the app requires either a WIFI connection or a cell network connection to access the Internet and the map.

  • during busy periods, the OSM server may be slow to render on your device. Sometimes the pop up fails to display when an object is touched.
    Just try again.

Credits: some free images used in the tutorial curtesy of and designed by Dreamstale.

Notes: The Map control cannot be moved once placed on the Screen. When building an app using the control you might want to place the Map in a Layout so you have control of your GUI.

Resources:


Regards and great coding :slight_smile:,
Steve

8 Likes

Dear @SteveJG ,
thanks for nice tutorial and let me wish you a happy New Year !
Can you suggest what options do I have to load attached relation geojson onto my map in AI application?
I'd prefer simple import but MapCollectionFeature.FeaturesFromGeoJSON fails. Alternativelly I may try to manually convert it to
or shall I manually convert it to FeatureCollection having just Markers and poligons similar to one that you used in your map Example part 1 (although it will be complex especially with outside/inside) . Of course I'm looking for simple and "the right way" to do it.

Best regards,
Kuba

{
  "version": 0.6,
  "generator": "Overpass API 0.7.59 e21c39fe",
  "osm3s": {
    "timestamp_osm_base": "2023-01-01T15:12:25Z",
    "copyright": "The data included in this document is from www.openstreetmap.org. The data is made available under ODbL."
  },
  "elements": [

{
  "type": "relation",
  "id": 6297631,
  "members": [
    {
      "type": "way",
      "ref": 423712604,
      "role": "outer"
    },
    {
      "type": "way",
      "ref": 423720613,
      "role": "outer"
    }
  ],
  "tags": {
    "boundary": "protected_area",
    "gid": "110525",
    "kodinspire": "PL.ZIPOP.1393.UE.1424043.404",
    "leisure": "nature_reserve",
    "name": "użytek 423",
    "protect_class": "19",
    "protection_title": "Environmental use",
    "protection_title:pl": "Użytek ekologiczny",
    "source": "Generalna Dyrekcja Ochrony Środowiska",
    "type": "multipolygon"
  }
},
{
  "type": "node",
  "id": 4232717224,
  "lat": 52.7031640,
  "lon": 21.0409504
},
{
  "type": "node",
  "id": 4232717228,
  "lat": 52.7032390,
  "lon": 21.0415835
},
{
  "type": "node",
  "id": 4232717238,
  "lat": 52.7033905,
  "lon": 21.0407787
},
{
  "type": "node",
  "id": 4232717240,
  "lat": 52.7034343,
  "lon": 21.0408481
},
{
  "type": "node",
  "id": 4232717243,
  "lat": 52.7034432,
  "lon": 21.0417187
},
{
  "type": "node",
  "id": 4232717244,
  "lat": 52.7034457,
  "lon": 21.0393029
},
{
  "type": "node",
  "id": 4232717250,
  "lat": 52.7034912,
  "lon": 21.0389532
},
{
  "type": "node",
  "id": 4232717251,
  "lat": 52.7035028,
  "lon": 21.0401945
},
{
  "type": "node",
  "id": 4232717257,
  "lat": 52.7035788,
  "lon": 21.0395904
},
{
  "type": "node",
  "id": 4232717263,
  "lat": 52.7036492,
  "lon": 21.0386949
},
{
  "type": "node",
  "id": 4232717278,
  "lat": 52.7036848,
  "lon": 21.0401860
},
{
  "type": "node",
  "id": 4232717288,
  "lat": 52.7037451,
  "lon": 21.0396303
},
{
  "type": "node",
  "id": 4232717293,
  "lat": 52.7037916,
  "lon": 21.0388544
},
{
  "type": "node",
  "id": 4232717294,
  "lat": 52.7037916,
  "lon": 21.0388547
},
{
  "type": "node",
  "id": 4232717296,
  "lat": 52.7038330,
  "lon": 21.0392983
},
{
  "type": "node",
  "id": 4232717298,
  "lat": 52.7038674,
  "lon": 21.0400352
},
{
  "type": "node",
  "id": 4232717299,
  "lat": 52.7038827,
  "lon": 21.0398320
},
{
  "type": "node",
  "id": 4232717300,
  "lat": 52.7039044,
  "lon": 21.0400637
},
{
  "type": "node",
  "id": 4232717302,
  "lat": 52.7039593,
  "lon": 21.0406523
},
{
  "type": "way",
  "id": 423712604,
  "nodes": [
    4232717302,
    4232717240,
    4232717243,
    4232717228,
    4232717224,
    4232717238,
    4232717251,
    4232717278,
    4232717298,
    4232717299,
    4232717300,
    4232717302
  ]
},
{
  "type": "way",
  "id": 423720613,
  "nodes": [
    4232717257,
    4232717244,
    4232717250,
    4232717263,
    4232717293,
    4232717294,
    4232717296,
    4232717288,
    4232717257
  ]
}

  ]
}

Hello Kuba.

Part I of the tutorial shows the simple way. There is no very simple way. :cry:

You may need to manually convert the json to one having only Markers and Polygons.but if you only place Polygons you might not have issues.

Your downloaded map from io has stuff the FeatureCollection does not require. I would redo your io map showing ONLY the polygons. You only need the Polygons. That json can be converted to and used as a FeatureCollection. Add Markers to your app later. Your desire to post everything you require on the io map complicates working with the json. Simplify and that might work.

Good luck.

Thanks a lot @SteveJG.
I'll have to learn more about overpass syntax to see if it can output ready-to-use polygon out of this relation (boundary=protected_area btw)
HNY , Kuba

Is this familiar Kuba? The polygon is the result of the points you supplied.

21.0408481],[ 52.7034432, 21.0417187],[ 52.7034457, 21.0393029],[52.7034912, 21.0389532],[ 52.7035028, 21.0401945],[ 52.7035788, 21.0395904],[ 52.7036492, 21.0386949],[ 52.7036848, 21.0401860],[ 52.7037451, 21.0396303],[ 52.7037916, 21.0388544],[52.7037916, 21.0388547],[ 52.7038330, 21.0392983],[ 52.7038674, 21.0400352],[ 52.7038827, 21.0398320],[52.7039044, 21.0400637],[52.7039593, 21.0406523]]

It appears the points are not in sequence/order. Seems to be random survey points which will not result in a regular polygon. The points have to be in sequence.

What happens when points placed in proper order ( "type": "way",
"id": 423720613,
"nodes": [
4232717257,
4232717244,
4232717250,
4232717263,
4232717293,
4232717294,
4232717296,
4232717288,
4232717257

[[ 52.7035788, 21.0395904],[52.7034457,21.0393029],[52.7034912,21.0389532], [ 52.7036492,21.0386949], [ 52.7037916, 21.0388544],[52.7037916,21.0388547],
[52.7038330,21.0392983],[ 52.7037451,21.0396303],[ 52.7035788, 21.0395904] ]

polygon2
:astonished:

You can do the other polygon.

Happy New Year,
Steve

@rkuba To use geojson.io to provide a FeatureCollection for your Project, you might find this solution useful. This is the advice made in Custom Map Overlay Part I to provide the overlays you seem to be looking for. :slight_smile:

  • Use the Polygon tool provided by geojson.io to design/provide your Polygons you want in the FeatureCollection or as individual Polygons.
  • Save the map with only the Polygons using the Save Menu as a geogson (you can also provide other objects .. Markers etc. but if you add anything other than polygons, complicates how you use the FeatureCollection).
  • the Web page will provide you with a file called map.geojson when you save the map. You can use it in either of two ways (1) drag the contents of the file map.geojson as shown in the diagram to a FeatureCollection.FeatureCollectionFromGeoJson with a Text block attached (yes, just highlight it and drag/drop) or (2) load the map.geojson into Media and use the File control to populate the FeatureCollection. Make sure you add a FeatureCollection to the Map in this case first.
  • display the two Polygons when you load your aia.

Happy New Year
Steve

Dear @SteveJG
Thanks for all yr suggestion.
Re using GUI of https://geojson.io/ :no-go as I get the data from osm and must process it autmamatically
Re Simpler data : OSM (for this type) provides only this format
Re conversion: in progress - takes me a while as it requires first consolidation ways that are in fact parts of polygons into polygons, then substituting it's node ids with coordinates and then converting into poly taking into account that 1st is outer, remaining ones should be inner). As it is more complex than expected, I'm concentrating on other parts of the app (If I make it I'll post here final conversion blocks).
Regards and thanks again, Jakub