Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
World Map in UI
-
Even though I haven't been posting in a while, I've had my head down on a few big projects.
I need to create a map of the world with selectable regions in Pythonista UI.
Would this be possible? Any suggestions? Thanks!
-
import ui # try these various urls... url = 'http://www.openstreetmap.org' url = 'http://wiki.openstreetmap.org' url = 'http://maps.google.com' url = 'http://earth.google.com' url = 'http://esri.com' url = 'http://www.arcgis.com/home/webmap/viewer.html' url = 'http://raphaeljs.com/world' webview = ui.WebView(title='Open Street Maps') webview.load_url(url) webview.present()
The Raphael JavaScript one is hilighting countries as the user clicks. Perhaps some of the JavaScript oriented folks on this forum can explain how to use the delegate to get the user choice back to your Pythonista script.
-
@techteej - you are saying that you want to do the map in Pythonista UI. Do you mean pure python and not using the WebView and JavaScript?
There has been a lot of recent interest in doing portions of a ui here using WV/JS as a first class ui component or widget. Using SVG has been discussed. Pythonista has a very capable canvas with many of the same methods provided by many of the JS libraries for vector support. It does not support the full interactive SVG model though. You could do the map using layers, but you will need to hunt down an SVG reader and doing any touch handling and animation by hand.
This really makes me wonder why there are sooo many JS vector libraries out there to enhance the HTML5 canvas.
Have a look at this review to get an idea of some of the features and tradeoffs going on in the JS/HTML5 world: http://crunchify.com/my-favorite-5-javascript-canvas-libraries/
-
Here is an example of using a javascript library integrated with a ui
https://github.com/jsbain/CodeMirror/
The main tricky bits:
-
webview.load_url
does accept file names, as long as the abspath is used. -
I found it incredibly difficult to detect the current script path, which worked in all cases of : run from the editor, run from the action menu, run from shellista at the time, instantiated as a class and run using methods. Hence the acrobatics using the inspect module to figure out current frame, and then determine the relative path of the html file. Unless you hard code pathnames, you'll need to do something like that.
-
The html can load scripts using relative paths, e.g in this case the html was located in a demo folder, and the javascript under the lib folder within the main project, so the html referenced the scripts using
<script src="../lib/codemirror.js"></script>
-
in my case, all actions were initiated by the python, and so it was easy to use
eval_js
commands to set or get the state of the javascript, for instance when loading/saving. It may be obvious, but usejson.dumps
when sending data to the javascript. I didn't seem to have to use json.loads when interpreting the result ofeval_js
. -
I have experimented with having the javascript call python. The trick is to implement a custom uri scheme, and implement
webview_should_start_load
. In your javascript, you would usewindow.location.assign(url)
to request the new url, which is then handled by the webview (which would return False, if memory serves)
-
-
I'll add that doing javascript within the pythonista environment is one of the most frustrating endeavors one can imagine, since javascript basically fails silently in this environment, with no good way to debug on a iDevice.
-
Awesome detail guys but...
Would it be possible to get a working example that starts out with something like:
import ui url = 'http://raphaeljs.com/world' webview = ui.WebView(title='Raphael JS World') webview.load_url(url) webview.present() # and ends up with: print('The country that you clicked on is {}!!'.format(get_clicked_country()))
-
@ccc Thanks. This is what I was looking for.
-
https://github.com/jsbain/worldmap.git
This is simply the Raphael world example, with two lines added to index.html (indicated with //JB comments) one to set window location to our custom uri, the other to set the title of each country drawn in the path attr's.
The callback is handled in the hover callback, and uses window.loction.assign to call a custom uri (world://countryname). The delegate is about as simple as it could be, splitting and un quoting the netloc of our custom uri.
If I were doing this for real, I'd strip away a lot from index.html so that we only have the world shown, to make it look more like a native object.
-
Very impressive. Thanks much.