I've used Google Maps in a native Android app, and used a similar map view in an iOS native app, and I've integrated a couple of plugins into a Gideros app. I've never created a Gideros plugin.
That said, how monumental a task would it be to create a mapping plugin? Has anyone explored it? I'd want a screen that would allow users to zoom and pan, show crosshairs or some other marker of a selected position, and maybe overlay icons at selected coordinates. I'm considering developing this plugin, and I'm trying to get a sense for how much work I may be looking at.
I see others have asked about such a plugin, and I'm contemplating trying to create it. Has anyone else considered creating such a plugin?
I'd be interested to hear from anyone who's worked on custom plugins, but especially those with a common interface between Android and iOS. Any thoughts?
PaulH
Comments
I tried with this link
http://giderosmobile.com/forum/discussion/1025/step-by-step-how-to-write-a-c-plugin-and-deploy-it-to-the-desktop-windows-player/p1
but still I couldn't even testing it with Android. I know there are a few guidelines to android here
http://giderosmobile.com/forum/discussion/830/creating-a-simple-android-plugin/p1
But I believe that @ar2rsawseen can give you better information about your question because, he has developped some plugin in Gideros Labs, both iOS and Android
[-] Liasoft
1) you create classes with static methods (ObjectiveC and Java) to manipulate all the stuff in the maps you need
2) then you create a C++ class to wrap it (through JNI for Android and .mm file for ObjectiveC)
3) then I usually create plain C interface for this class, so it would be independent of the language
4) and then I write bindings to the Lua for this C interface
That is about it. Some source examples are provided in the Gideros installation directory (Google billing plugin is a great source to start with, the one I used to learn plugin development)
But if you have any specific questions, I can help and answer
I know that Maps plugin was requested couple of times, and I would really want to promise to make one soon, but for now there are a lots of things I need to do
I was actually again thinking on creating common Maps interface, because there are Goolge maps for Android, then Apple maps for IOS, then Amazon maps for kindle and then Nokia Maps for Nokia X. So you see the point
PaulH
Unless...
Ar2rsawseen, you've mentioned before you've considered developing this plugin. I'm sure you could develop this one in a fraction of the time it would take me. I'd be willing to pay for this plugin if you'd consider taking it on.
Any chance of that?
Paul
But we could try to split the work.
Do you have any idea for Lua interface?
As in which classes, methods, event would be available on lua side, that would be enough to control Map?
Thanks for being willing to help with this!
Paul
Basically I'd be looking for fairly thin cover over native map functions.
The bare minimum functionality from my perspective is the ability to position a map by latitude & longitude, to set the zoom level, to switch between different map styles (street vs satellite), to add markers, and handle touch events. For the markers the bare minimum functionality would be to specify a label or title for each, and handle touch events.
It might be helpful, though not necessarily a required feature, for a map to use the Sprite base class, or at least support addChild() like a Sprite. That would make it possible to use Sprites to implement custom map markers or overlays in lots of ways. If that’s feasible, it might not be necessary to support the markers native to the underlying map. I suppose another option is to have the Map be only that (not a sprite or container for sprites) and leave it to users to create a View who’s children would include one map and any number of Sprites that overlap it.
The Map class would support these methods:
function Map:init(latitude, longitude, zoom, witdth, height, positionX, positionY)
function Map:setPosition(positionX, positionY) – position the Map on the screen, relative to its parent, whether or not Map uses Sprite as a base class
function Map:setType(mapType) -- support "normal", "satellite", "terrain", "hybrid" (satellite with roads overlaid)
function Map:setCenter(latitude, longitude) -- move the map to view the specified coordinates
function Map:setZoom(zoomLevel) -- control the zoom level of the map, units TBD
function Map:setLocationEnabled(locationEnabled) -- at least for Android, enable the default “go to my location” button overlaid on the map
function Map:onMapClickListener( event handler...)-- handle touches on the map, i.e. for selecting a location
function Map:addMarker(marker) -- add a default style marker to the map – see below
function Map:clear() -- remove all markers
function Map:addEventListener(eventType, eventHandlerFunction) -- Support eventType "move", detecting when the map has been moved manually. Not strictly necessary, but useful when supporting navigation, or any scenario where you might program the app to move and/or zoom the map automatically, unless the user has manually moved it.
function Map:getLocationPosition(latitude, longitude) -- returns x, y of specified location relative to the Map; This would only be necessary if Map supports Sprites as children, in which case this would be used to position the sprites.
function Map:getLocation() returns latitude and longitude of center of map
The MapMarker class, if markers are implements as a cover over native map markers rather than Sprite children of the map, would support these methods:
function MapMarker:init(latitude, longitude, title) -- Sets the coordinates and name of a marker
function MapMarker:setAlpha(alpha) – sets transparency of marker
function MapMarker:setHue(hue) -- 0 to 360, angle to position on color wheel, from 0 (red) through orange and yellow to green (180) through blue and purple back to red (360.) Some other set of hue values could be used and mapped to platform specific values in the native code.
function MapMarker:addEventListener(eventType, eventHandlerFunction) -- Support clicks/taps on each marker
function MapMarker:setId(id) -- A generic ID one could use to associate a specific marker with additional data
function MapMarker:getId(id) -- A generic ID one could use to associate a specific marker with additional data
funciton MapMarker:getTitle() -- Returns the title specified in init(). Not strictly necessary if IDs are supported, as the calling code could keep track of the titles of all markers along with any other data specific to each marker that was added.
function MapMarker:getLocation() -- Returns latitude and longitude specified in init(). Not strictly necessary if IDs are supported, as the calling code could keep track of the coordinates of all markers along with any other data specific to each marker that was added.
-- Not including functions to alter existing markers. That's probably rarely used, and one can use a function to clear the map and add updated markers if necessary.
Thoughts?
Paul
Likes: antix
But I do think you need MapMarker:setTitle() to make it easier to use, and be more complete (every get should be complimented with a set)
Sprite is drawn over GL surface, and Map can be either under or over GL surface (if it would be under, we would not see it, so only over).
So positioning will be absolute, over all screen, but still would count in scale modes and logical dimensions (so 200px width for Shape would be visually the same for map). That is possible.
One question that I have though, do all platforms (Android and iOS for now) support all these features for Maps?
So let me try to prepare the Lua part, and then we can try to match it to some native methods
I haven't dealt with markers in iOS yet, but will look into that.
Do I understand correctly that we won't be able to display any sprite over the top of the map, since the sprites can only appear on a GL surface, and the GL surface can't have a transparent background so we can't put a GL surface over the map to expose both?
If that's the case, then we can skip the function Map:getLocationPosition(latitude, longitude) which isn't built in to either native map system, and the main reason I thought it would be worth writing was for overlaying sprites over the map. We'll have to support markers strictly through the native methods. It's very straightforward on Android. I'll educate myself further on the iOS side.
Paul
Likes: antix
In theory a LUA based one would be slower but really how fast does a map thing need to be?
If you don't make a lot of requests it should be fine, otherwise you may need a contract with some map tile provider, or you could set up your own tile server from OpenStreetMap data.
Have a look at MapTileSource file
However these tile sources are direct access to google server, largely unofficial way of getting their maps...
You can check an example of an iOS app here:
Open Studios by Ian Chia
https://appsto.re/au/tvSjx.i
Happy to share the code if it would be useful.
Best,
- Ian
Likes: antix
I'm going to continue to pursue the native map APIs. My next step will be to try to work on the Android native Java to setup a map with hardcoded values. Hopefully that will make it fairly straightforward to connect the parameters coming in through the plugin framework.
Paul
Likes: keszegh, totebo, antix
Also I'm proposing eliminating the Marker as a separate class. Instead I've added functions to manipulate markers directly within the Map class. Adding a marker returns an index, which can be used to handle clicks, get/set the title and coordinates, and set the hue and alpha.
Lastly I've added show/hide functions, since we will of course need to control when the map is and isn't on the screen.
I'm attaching the Map.java file that implements this for Android, and a text file explaining the steps to use this class to add a Google map to a Gideros app. The map class is fully functional. Next we need the plugin to provide access to the functions in this class from Lua.
Ar2rsawseen, does this give you what you need to create the plugin for Android? If so I'll get started on the same native implementation for iOS.
The following is the interface as I've implemented it in Java for Android:
Map:new(): Constructor
Map:show(): Display the map
Map:hide(): Hide the map
Map:setDimensions(int width, int height): Set size of map in pixels
Map:setPosition(int x, int y): Set position of map on screen in pixels from top left
Map:setCenterCoordinates(double latitude, double longitude): Center the map around the specified coordinates
Map:setZoom(float zoom): Set zoom level from 0 (very large area) to 19 (zoomed in close)
Map:setType(int map_type): Switch between MAP_TYPE_NORMAL, MAP_TYPE_SATELLITE, MAP_TYPE_HYBRID, MAP_TYPE_TERRAIN
Map:setMyLocationEnabled(boolean enabled): Turn on/off the “My location” button
Map:mapClicked(): Return true if the map was clicked since last call
Map:getMapClickLatitude(): Return latitude of last click on the map
Map:getMapClickLongitude(): Return longitude of last click on the map
Map:hasMoved(): Return true if map was moved since last call
Map:getCenterLatitude(): Returns latitude of center of area shown
Map:getCenterLongitude(): Returns longitude of center of area shown
Map:clear(): Remove all markers
Map:addMarker(double latitude, double longitude, String title): Adds a marker, and returns an index that can be used to access it
Map:setMarkerTitle(int marker_idx, String title): Sets the title of the specified marker
Map:setMarkerHue(int marker_idx, float hue): Sets the color of the specified marker in degrees around a color wheel, from red at 0 through the colors and back to red at 360. Defined for convenience: MAP_MARKER_RED, MAP_MARKER_ORANGLE, MAP_MARKER_YELLOW, MAP_MARKER_GREEN, MAP_MARKER_BLUE, MAP_MARKER_PURPLE
Map:setMarkerAlpha(int marker_idx, float alpha): Set the alpha (transparency) of the specified marker
Map:setMarkerCoordinates(int marker_idx, double latitude, double longitude): Moves the specified marker to the given coordinates
Map:String getMarkerTitle(int marker_idx): Sets the title of the specified marker
Map:getMarkerLatitude(int marker_idx): Returns the latitude of the specified marker
Map:getMarkerLongitude(int marker_idx): Returns the longitude of the specified marker
Map:getClickedMarkerIndex(): Return the index of the last marker clicked, if any since last call
Likes: antix, simwhi, pie