AI2 Flat Maps - unchain yourself from Google Maps by sjg
Plotting to a map on a device not having a WIFI or network connection can be accomplished if you have a non-Google flat map to display location and plot the GPS location onto the flat map. If your device is connected to the Web the choice of using a flat map or a Google map is easy. Use the Google Map or Google Static Map.
The Android device requires a connection to the Web to use the Google Maps. Follow the tutorial referenced here http://www.appinventor.org/Chapter6 and plot location information to a map. Control the zoom with coding that points to the url to the Google map or use Google’s Static Map API.
You might copy the static map as an image and use Google’s Mercator Map projection in your app (if you can figure out the coordinates of the map corners and you properly provide attribution to Google). Finding the corners of a Google Mercator map or map tile is difficult whether you use AI2 or Windows etc. This tutorial does not go there.
A flat map is …..
An easy way to get a flat map to use in your non-Google (or OmR) map app is to design a specific map at http://www.openstreetmap.org/ The organizations does require you to register but then you can make the free maps you can download to your computer.
The map above was obtained from OpenStreetMap. Creating a map using OpenStreetMap is a free service. This map is used as an example to demonstrate how everyone can free themselves from Google Map tyranny later in the tutorial. The map image is 512 pixels x 512 pixels. These dimensions are of a size that renders on a phone or a tablet, but at reduced scale.
https://groups.google.com/forum/#!category-topic/mitappinventortest/BTmcps4JkMI
2) You can use the openstreetmap image, with your coordinates (the x and y positions of the locations of buildings, restaurants etc on the Canvas.BackgroundImage) and work as you are doing. Make a OpenStreetMap at a higher detail level and you get a second zoomed image. Then, use the second map to "zoom" to the buildings you want showing more detail posted on a second Canvas.BackgroundImage Replicate the coding the coding you used so far and you can also place a sprite on that object or just make the more detailed map visible. (Hide the second Canvas when you do not want it).
3) You can use a different way to locate the sprites on your map:
The diagram attached is intended to help understand concepts. If you do not know and understand this stuff,you can not plot GPS 'pin's on a user provided map using conventional methods.
World Map Coordinates:
How the GPS reports location information. Seafaring navigators use
Degrees, Minutes, Seconds (or DMS) to report latitude and longitude;
GPS receivers (and computer programmers) use decimal degrees. If it
were only that simple. Decimal degrees West of the Prime Meridian are
reported as 0 to -180 degrees, East of the Prime Meridian are
reported as 0 to + 180 degrees decimal.
When you use a custom map to display information on your device, you must relate World Coordinates to Screen Coordinates. If your map is entirely East of the Prime Meridian or entirely West of the Prime Meridian, converting from Map Coordinates to Screen Coordinates is rather straight-forward (I did not say simple, it is complex). If you have a map that crosses the Prime Meridian, the math gets complex.
The Canvas screen is defined by the size of the Canvas in pixels. See the Screen Coordinates diagram above. Assuming your map example is defined with the Canvas dimensions as 512 x 512 you get something like shown (the diagram is just to illustrate the concept) The black coordinates is what your map generation program provides, converted to decimal degrees, the green is what I interpolate as the coordinates for the remaining map corners..
To plot a location, on the map image (let’s post it in the very center of the image in this example ( 44.59056 , 18.10509) You plot a point on the Canvas 'screen' at 256, 256.
To do that using the
information from the LocationSensor, you write a procedure to
translate the location coordinates to Screen
coordinates. See below is an example of one
way to do it.
If you always use the same User Map with the same dimensions, your problem is solved.
if you want to do zooming in and out, you got a lot of work to do.
I converted the DMS from an openstreet map to decimal degrees. I did not keep all the decimal places. There are several reasons: 1) a GPS only reports five decimal places and 2) when you convert the World map coordinates to Screen coordinates, almost all of this precision is lost in rounding at the map scale we are using in this example.
When you plot a pin or icon at any GPS coordinate it posts to an approximate location. Can this get any more difficult? Yes, certainly. For instance, the map you use is composed of pixels, a pixel's height is larger than its width, so this size relationship introduces distortion in the posted map image. Do you NEED to correct for this? Possibly not, but you can compensate mathematically by adjusting the World to Screen and Screen to World conversion algorithm. YOU have to write these procedures.
Posted is an image of the algorithm I use to convert the map Longitude to a screen coordinate (mapW2SxLin). Do that for the Latitude and if you want to extract information from the map later, you need to do the reverse to get from Screen Coordinates to World Coordinates.
The four functions are used to convert latitude and longitude information are AI2 block procedures.
The algorithms to convert World Coordinates to the Screen coordinates of the Canvas control were derived from Pascal code here: http://www.ibrtses.com/delphi/dmcs.html
and is summarized:
Mapping
world and screen coordinate systems to each other is
done by
scaling with respect to an offset.
be the world window be
defined as:
[xLow..xHigh,yLow..yHigh], the coordinates are
of type float
be the screen window be defined as:
[tlx..brx,tly..bry], the coordinates are of type integer
the
following function do the conversion :
function
mapW2SxLin(xf:float):integer;
begin
result:=round(tlx+(xf-xlow)*(brx-tlx)/(xhigh-xlow));
end;
function mapW2SyLin(yf:float):integer;
begin
result:=round(bry-(yf-ylow)*(bry-tly)/(yhigh-ylow));
end;
function mapS2WxLin(xs:integer):float;
begin
result:=xlow+(xs-tlx)*(xhigh-xlow)/(brx-tlx);
end;
function mapS2WyLin(ys:integer):float;
begin
result:=yhigh-(ys-tly)*(yhigh-ylow)/(bry-tly);
end;
The above algorithms are from: http://www.ibrtses.com/delphi/dmcs.html and written in a version of Pascal.
A last note, be aware that the AI2 LocationSensor uses periods as a decimal separator. Most Europeans and others outside North America use a comma (,) so you may have to convert the LocationSensor information string to replace the (.) period with a comma (.) to get the App User's location to plot on your map.
Build the app - Plot to Any Map
This app is a demonstration of techniques that can be used with App Inventor to plot coordinate information to any Flat Map. If the developer is willing to write some additional code to correct for the variation in separation of degrees of latitude that varies on a Mercator map, that map projection can be used too. In fact, if the Mercator map you use displays only a few miles North and South and East and West, the plotting error invoked by using a Mercator map as a flat map is minimal and probably can be ignored (unless the developer requires precision).
The app has three flat maps, of very different origins and scales. The three maps demonstrate the usefulness and limitations of using a flat map within an App Inventor 2 app.
This Nasa image (NASALivingEarth.jpg) of the World is displayed as a flat map. The left edge of the image has coordinates of -180 deg. West longitude, the right edge of the image has coordinates of +180 deg. East longitude.
This map is by an amateur radio operator xxxxxx and was originally usa_east.gif, converted to usa_east.png for use in App Inventor. Coordinates of the corners are provided in a separate file.
This image is from OpenStreetMap showing an area of Manhattan, NY.
A fourth type of ‘map’ consisting of the outline of a building or a fantasy map can also be used as a screen to plot to. It is easy to set up. Instead of using gps coordinates, use the Canvas screen coordinates to locate objects .