(google) maps with android+processing

edited January 2014 in Android Mode

osX 10.6.8 processing 2.03 Android sdk 2.2.3

android sdk installed and running fine. I need to display dynamic & interactive maps according to the user gps location, which i get using ketai lib (or other) but i cannot find the way to display maps: ---- unfolding lib does not work with p5 2.0 ---- googlemapper lib does not work with android mode i have tryed to add an import to googlemaps using this code after having installed the googlePlayService on the SDK manager::

import com.google.android.gms.maps.*;
import com.google.android.gms.maps.model.*;
import android.app.Activity;
import android.os.Bundle;

import android.content.Context;           //network connection
import android.net.ConnectivityManager;
import android.net.NetworkInfo;

public class MapPane extends Activity {

    @ Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.map_activity);


        GoogleMap map = ((MapFragment) getFragmentManager()
                .findFragmentById(R.id.map)).getMap();

        LatLng bastelica = new LatLng(42.000921, 9.050197000000026);

        map.setMyLocationEnabled(true);
        map.moveCamera(CameraUpdateFactory.newLatLngZoom(bastelica, 13));

        map.addMarker(new MarkerOptions()
                .title("bastelica")
                .snippet("sanpiero corsu")
                .position(bastelica));
    }
}

----- but it fails when compiling:: No library found for com.google.android.gms.maps No library found for com.google.android.gms.maps.model

what can i do?

thanks

Answers

  • Never tried it on Android, but there is an Unfolding beta for Processing 2. http://unfoldingmaps.org/rca

    Would be great if you give it a try, and report back.

  • This implementation will surely fail in a Processing environment. It relies on Android's native MapFragment, which cannot coexist peacefully with a Processing sketch (unless the sketch is exported into Eclipse and further modified there). It may be possible to use Google Maps in some way, but I would first rely on a Processing library for maps.

  • dear tinagel,

    i have tried with your new version; it runs in java mode but when i open the simplest example ("simpleMap") the emulator crashes when "installing the sketch":: FATAL EXCEPTION: Thread-11 java.lang.NoSuchMethodError: processing.core.PApplet.loadImage at de.fhpotsdam.unfolding.tiles.TileLoader.getTileFromUrl(Unknown Source) at de.fhpotsdam.unfolding.tiles.TileLoader.run(Unknown Source) at java.lang.Thread.run(Thread.java:1019) ------ this is exactly the same error i get with the modestmaps lib ------ is it a problem with the loadImage function or with map.draw() i dont know but the error message seems to designate the first one (assuming the url to be good!)

    if you get a way to solve that.... thanks

  • dear calsign,

    ----as for the import (import com.google.android.gms.maps.*;...) i finally get the way to solve that; you have to create a code folder, find & get the map.jar which is into the addons folder in the sdk, make a clone and put it in the code folder of the sketch. ----as for the code, i have modified it according to the initial error messages i got( for "setContentView(R.layout.map_activity)), (that is solved also); as for MapFragment, i dont know, i am afraid that you are right!...I 'll tell you the issue as soon as possible!

  • akenaton,

    Again, I have no experience with Android. It seems that SimpleMapApp sketch cannot load map tiles from the web.

    Does the following web image loading example work on your environment?

    https://github.com/processing/processing-android/blob/master/examples/Basics/Web/LoadingImages/LoadingImages.pde

    They mention you must ensure to have "INTERNET" permission enabled. Might that already be the issue?

  • dear tn,

    1--- error in your code: img1+ no "size" with android 2 ---the url "http://processing.org/img/processing_cover.gif" is 404, so.... -----changing the url, it works fine on android (and of course with java mode)

  • Well, that example is from the official Processing Android repo. But did you have to change permissions? Or did it work without?

    And in any case, it seems we need to dig actually into Unfolding for Android. Anyone up for that?

  • dear tn, of course all permissions for internet are in the manifest file. I know think (having tested your example - img1 added, size() deleted, url changed to a working one-) that the problem is between the tileloader and processing. Futhermore, as i have said, i get exactly the same error message with modestMaps lib. I shall try to get a glance in the source java and tell you if i find some work around.

  • Ok, seems the Processing-Android branch does not provide the loadImage(filename, extension) method anymore.

    Meaning, currently Unfolding won't work. I will try testing it end of next week.

  • no, i dont think so, i can download images from the web without problem, but not tiles, and i think that is linked with the java code in modestmaps a

  • nd Unfoldings: if your contructor refers to size, (dimensions etc) it cannot work (i am afraid!)

  • stupid example:

    import apwidgets.*;
    PWidgetContainer widgetContainer; 
    PButton button1;
    PButton button2;
    
    import android.content.Context;           //network connection
    import android.net.ConnectivityManager;
    import android.net.NetworkInfo;
    import ketai.sensors.*;
    
    import com.modestmaps.*;//maps providers
    import com.modestmaps.core.*;
    import com.modestmaps.geo.*;
    import com.modestmaps.providers.*;
    
    InteractiveMap map;
    
    PImage carte;
    
    int mW=600;////for zooming
    int mH=800;
    int inc = 10;
    boolean plus= false;
    boolean moins= false;
    
    double mapCenterLat;///arbitrary=== could be replaced by .location (from ketai or others) but for tests
    double mapCenterLon;//the same
    double mapAltitude;
    
    KetaiLocation location;
    
    void setup() {
    
      orientation(PORTRAIT);
    
    
    
      widgetContainer = new PWidgetContainer(this); //create new container for widgets
      button1 = new PButton(400, 500,60,60, "+"); //create new button from x- and y-pos. and label. size determined by text content
      button2 = new PButton(400, 565, 60,60,"-"); //create new button from x- and y-pos., width, height and label
      widgetContainer.addWidget(button1); //place button in container
      widgetContainer.addWidget(button2);
    
      textAlign(CENTER, BOTTOM);// les 2 paramètres fixent la position générale de la boite texte: ici on centre le tt en largeur et la dernière ligne sur le bas(bottom)
      textSize(18);
    
      mapCenterLat = 42.000921;
      mapCenterLon = 9.050197000000026;
      mapAltitude = 781.45678989;
      int zoomLevel = 12;//entre 0 et 18 ou 20
      ///mapType could be definend there
    
    
      ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
      NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
    
    
      if (networkInfo != null && networkInfo.isConnected()) {
        println("connection ok!");
    
    
        // pbs URL, etc
        try {
    
    
          carte = loadImage("http://maps.googleapis.com/maps/api/staticmap?center="+mapCenterLat+","+mapCenterLon+"&zoom="+zoomLevel+"&size="+mW+"x"+mH+"&sensor=true");
        }
        catch (NullPointerException npe) {
          println("probleme url");
        }
      }
    
      // pas de connection...== erreur
      else {
        println("pas de connection");
      }
    
    
    }
    
    void draw() {
    background(50);
    
      image(carte, 0, 0, mW, mH);
    
    
      if (location.getProvider() == "none"){
        text("pas de location", 0, 0, width, height);
    
      }else{
    
          text("Latitude: " + mapCenterLat + "\n" + 
          "Longitude: " + mapCenterLon + "\n" + 
          "Altitude: " + mapAltitude + "\n" + 
          "Source: " + location.getProvider(), 0, 0, width, height);  
    
    }
    
    
    }
    
    void onClickWidget(PWidget widget){
      ///println("jexecute");
      if(widget == button1){ //bouton +
    
        plus = true;
       // println("plus=" + plus);
        mW= mW+inc;
        mH = mH+inc;
      }else if(widget == button2){ //or if it was button2
      // println("moins");
         moins = true;
         mW = mW-inc;
         mH = mH-inc;
      }
    
    }
    
    void onResume()
    {
      location = new KetaiLocation(this);
      super.onResume();
    }
    
    void onLocationEvent(double _latitude, double _longitude, double _altitude)
    {
      mapCenterLon = _longitude;
      mapCenterLat = _latitude;
      mapAltitude = _altitude;
      println("lat/lon/alt: " + mapCenterLat + "/" + mapCenterLon + "/" + mapAltitude);
    }
    
  • hello, for android it work

    /**
     * Loading Images. 
     * 
     * Loads an image from over the network. Be sure to have INTERNET
     * permission enabled, otherwise img will always return null.
     */
    PImage img1;
    String googleMaps; 
    void setup() {
      size(400, 400);
      googleMaps = "http://maps.google.com/maps/api/staticmap?center=45.464160,9.191614&zoom=3&size=400x400&sensor=true&markers";
      //img1 = loadImage(googleMaps,"png"); //for pc
      img1 = loadImage(googleMaps); //for android
    }
    void draw() {
      image (img1, 0, 0);
      image(img1, 0, 0);
    }
    
  • //leaving the mapModest lib or unfolding lib questions (which nead a lot of work for amdroid mode....)

    1) Is the emulator android mode possible for google maps in P5??? - it is possible in eclipse, but... 2) how to work with the R.java which is linked with the mapView (i have tried to put some .xml for that in the data folder but it does not work and programming i can only set the width and height args, not the mapView.LayOut iself :: R....@id) thanks

  • dear camperos, of course i know, it works: see my code! --- but that is a static map!---what to do if the user drag (and he will)??? - Knowing that googlemaps is not multithreaded? thanks!!!

  • akenaton,

    Just to clarify, the loadImage(fileName) method does work in Android, but the loadImage(fileName, extension) does not. It might be, we simply need to change this in Unfolding. Will come back to you in the next days.

  • dear tn,

    i dont understand ; in res/ there are not any extension but if you put the image in the classic data folder it runs normally:

        void setup(){
          orientation(PORTRAIT);
          PImage img = loadImage("essai.jpg");
          image(img,0,0);
        }
    
  • deat tn,

    excuse me, i understand now only what you explained & i agree with you; though i cannot see your java sources in the downloaded zip i think that your tileloader uses some method as "loadImage "thisimage", ".png") which of course is not the processing standard loadImage method... That is the reason why the sketch is correctly builded (on android) correctly installed and fails only after starting on the emulator, at the draw ()method. thanks and reguards

  • i have tried to write some code only to undestand what happens, but i cannot undestand why this code works with java mode and fails in the emulator (not compiling or installing or starting) - console tells (android mode) :: java.lang.NullPointerException at processing.core.PGraphics.image(Unknown Source) though the adress seems to be good and the image is loaded when java mode...Why??? here the code:

    import com.modestmaps.*;
    import com.modestmaps.core.*;
    import com.modestmaps.geo.*;
    import com.modestmaps.providers.*;
    
    InteractiveMap map;
    PImage carte;
     void setup(){
       int zoom = 10;
       double lat = 47.968056d;
       double lon = 7.909167d;
       OpenStreetMapProvider prov;
       prov = new OpenStreetMapProvider();
    
       String adresse = ("http://"+ prov.subdomains[(int)random(0, 4)]+ "tile.openstreetmap.org/"+getTileNumber(lat, lon, zoom) + ".png");
       ///String adresse = ("http://tile.openstreetmap.org/"+getTileNumber(lat, lon, zoom) + ".png"); //same result with or withoud subdomains)
    
       carte = loadImage(adresse);
       println (adresse);
     }
     String getTileNumber(double lat, double lon, final int zoom) {
       int xtile = (int)Math.floor( (lon + 180) / 360 * (1<<zoom) ) ;
       int ytile = (int)Math.floor( (1 - Math.log(Math.tan(Math.toRadians(lat)) + 1 / Math.cos(Math.toRadians(lat))) / Math.PI) / 2 * (1<<zoom) ) ;
        if (xtile < 0)
         xtile=0;
        if (xtile >= (1<<zoom))
         xtile=((1<<zoom)-1);
        if (ytile < 0)
         ytile=0;
        if (ytile >= (1<<zoom))
         ytile=((1<<zoom)-1);
        return("" + zoom + "/" + xtile + "/" + ytile);
       }
    
       void draw(){
    
        image(carte, 0,0);
    
       }
    
  • edited January 2014
  • dear camperos,

    as for me and using ONLY osm maps (in order to be more simple!)::

    1) - in the browser, all the links are working + "http://tile.openstreetmap.org/12/2156/1463.png") [without subdomains]

    2 )- java mode, with the above code: they work also

    3) - android : java.lang.NullPointerException at processing.core.PGraphics.image(Unknown Source) ?????!!!!!!

    (and of course in the manifest internet allowed)

  • edited January 2014

    OT: I also at the same time to your work I was looking for a system processing and arduino gps map in real time. I am currently trying with "Atlas Creator" and: http://processingjs.org/learning/basic/mousefunctions/, http://processing.org/examples/scaleshape, http://forum.processing.org/one/topic/mapping-gps-locations-to-a-2d-u-s-map.html

    beta version.
    doesn't work without PNG in loadImage
    
    float x,y;
    float bx,by;
    PImage maps;
    float mapX= 9.36678;
    float mapY=44.51225; 
    float xOffset = 0.0; 
    float yOffset = 0.0;  
    int time ;
    float Estart = 9.47;  
    float Eend = 9.25;
    float Nstart = 45.56; 
    float Nend = 45.45;
    float zoom =1;
    float zooom =1; 
    void setup() {
      size(800, 480);
     orientation (LANDSCAPE);
      ellipseMode(CENTER); 
     //////////////////////////////////////
     /////////////////////////////////////// 
    
     // maps = loadImage("MyAtlasMapHere.png");
    
     ////////////////////////////////////// 
    /////////////////////////////////////////
      time =millis();
    }
    void draw() 
    {  
      background(100);
      pushMatrix();
      if (mouseX >650 && mouseX <800 && mouseY >0 && mouseY < 130 && mousePressed) {
        zoom = zoom+0.01;
      }
      if (mouseX >650 && mouseX <800 && mouseY >330 && mouseY <480 && mousePressed) {
        zoom = zoom-0.01;
      }
      scale (zoom); 
    ///////////////////////////////////////////////////////////////////
      if (time+500 < millis()) {    //demostration variable coordinate 
        for (int i=0; i<100;i++) {  //demostration variable coordinate
          mapX = mapX+0.0000005;    //demostration variable coordinate
          mapY = mapY+0.000002;     //demostration variable coordinate
        }                           //demostration variable coordinate
        time =millis();             //demostration variable coordinate
      }                             //demostration variable coordinate
     /////////////////////////////////////////////////////////////////// 
      x = map(mapX, Estart, Eend, 0, 800);
      y = map(mapY, Nend, Nstart, 0, 480); 
       image(maps, x-768+bx, y-640+by  );  
         fill (255, 0, 0);
      ellipse(400+bx, 240+by, 10, 10);
    popMatrix();
    texto();
    } 
    void mousePressed() { 
      xOffset = (mouseX-bx); 
      yOffset = (mouseY-by);
    }
    void mouseDragged() { 
      bx = (mouseX-xOffset); 
      by = (mouseY-yOffset);
    }
    void texto() {
      // zoom =-zoom;
      fill (255, 0, 200, 50);
      rect (0, 440, width, 480);
      fill (0);
      textSize (20);
      text (mapY + "N", 10, 460);
      text (mapX + "E", 170, 460);
      textSize (120);
      fill (255,255,0,50);
      ellipse (730,50,80,80);
      ellipse (730,400,80,80);
      fill (0);
      text ("+",683, 85);
      text ("-",697, 437);
    }
    
  • dear camperos, i have tried your code; it compiles, starts and runs. But of course i cannot see your map; i have tried in my code with lat and long == your init values for mapX & mapY and i can see a map (africa???) - but when i tried to put the same map in YOUR code (with MY loadImage(adresse) method (changing of course lat and long) the map disappears, without any error message (and the buttons & text are ok)...Till now i get no explanation for that...See you later!!!

    PS: for getting the lat & long while dragging, i have found the same solution (mapping mouse values and coord)

  • dear camperos, dear tn,

    • i have tried a lot of things.

    -As for downloading the maps i am now sure that: ----the url used by openstreet maps or others (rows & col &zoom)+.png which work in java mode DOES NOT WORK in android - processing mode: why, i cannot understand. ----on the contrary the url for google maps (statics) does not work in java mode if you dont add "&.png" at the end of the query. ----but in android mode they only work without this .png (or .jpeg or...)

    --- dear camperos:: your scale() i think is not good:: you dont change the loaded map ----and i don t understand your translate in push matrix();

    so in this moment here is the code i use for getting maps from google. of course i have now to do the real job! [REAL TIME COORDs with ketai lib, saving markers, adding pictures and links!!!][bu, as we say in french language:: "à chaque jour suffit sa peine"]-- tell me if it "works" for you.....thanks & greetings

    import com.modestmaps.*;///now i t cannot work, like unfoldings, but i hope that!!!
    import com.modestmaps.core.*;
    import com.modestmaps.geo.*;
    import com.modestmaps.providers.*;
    
    import apwidgets.*;
    PWidgetContainer widgetContainer; 
    PButton button1;
    PButton button2;
    
    InteractiveMap map;//perhaps tomorrow???
    
    PImage carte;
    
    float xInit=0;
    float yInit=0;
    
    float xDeplace = 0.0;
    float yDeplace = 0.0; 
    
    
    boolean demarre = true;
    boolean bouge = false;
    
    int zoomL;
    

    ///at the beginning:: center(!!!) of corsica,where i live and that s the aim of the app

    double lat = 42.000921;//piana = 42.228741900000000000; cervione = 42.3310699;
    double lon = 9.050197000000026;//bonif = 9.1592689999999950//giraglia = 9.40547289999995
    
    float posX;
    float posY;
    float maxW = 42.3310699;
    float minW = 42.22874190000;//as for me "double" but when i try to map processing ask for float..?.
    float minN = 9.15926899999950;
    float maxN = 9.40547289999995;
    
    
    
    void setup() {
     // size(600, 600);
      orientation(PORTRAIT);
      background(0, 0, 0);
    
      zoomL = 7;
    
      OpenStreetMapProvider prov;/// here:: useless because the url provided by this function, though perfectly correct does not work!!!
    
      prov = new OpenStreetMapProvider();
    
      // String adresse = ("http://maps.googleapis.com/maps/api/staticmap?center="+lat+","+lon+"&zoom="+zoom+"&size=400x400&sensor=true");
      String adresse =  "http://maps.googleapis.com/maps/api/staticmap?center="+lat+","+lon +"&zoom="+zoomL+"&size=800x800&scale=2&maptype=hybrid&markers=color:blue%7Clabel:S%7C"+lat+","+lon +"&sensor=false";
      //String adresse = "http://b.tile.openstreetmap.org/"+getTileNumber(lat, lon, zoom)+".png";
      //String adresse =  "http://maps.googleapis.com/maps/api/staticmap?center=9.30,45.50 &zoom="+zoomL+"&size=800x480&scale=2&maptype=hybrid&markers=color:blue%7Clabel:S%7C9.30,45.50 +&markers=color:green%7Clabel:G%7C40.711614,-74.012318&markers=color:red%7Clabel:C%7C40.718217,-73.998284&sensor=false";
    
      map = new InteractiveMap(this, new OpenStreetMapProvider());
      println(adresse);
    
      //map.setCenterZoom(new Location(lat, lon), zoom);  
      carte = loadImage(adresse);
    
      widgetContainer = new PWidgetContainer(this); //create new container for widgets
      button1 = new PButton(10, 680, 60, 60, "+"); //create new button from x- and y-pos. and label. size determined by text content
      button2 = new PButton(10, 745, 60, 60, "-"); //create new button from x- and y-pos., width, height and label
      widgetContainer.addWidget(button1); //place button in container
      widgetContainer.addWidget(button2);
      textAlign(CENTER, BOTTOM);// les 2 paramètres fixent la position générale de la boite texte: ici on centre le tt en largeur et la dernière ligne sur le bas(bottom)
      textSize(18);
    

    // this library works well with android

      //println (adresse);
    }
    String getTileNumber(double lat, double lon, final int zoom) {/// this function returns the url for openStreetMaps; they seem to be ok but dont work!
      int xtile = (int)Math.floor( (lon + 180) / 360 * (1<<zoom) ) ;
      int ytile = (int)Math.floor( (1 - Math.log(Math.tan(Math.toRadians(lat)) + 1 / Math.cos(Math.toRadians(lat))) / Math.PI) / 2 * (1<<zoom) ) ;
      if (xtile < 0)
        xtile=0;
      if (xtile >= (1<<zoom))
        xtile=((1<<zoom)-1);
      if (ytile < 0)
        ytile=0;
      if (ytile >= (1<<zoom))
        ytile=((1<<zoom)-1);
      return("" + zoom + "/" + xtile + "/" + ytile);
    }
    
    void draw() {
    
      background(0, 0, 0);
      imageMode(CENTER);/// for camperos:: as the image mode is center, using this is meaning....
    
      if (demarre) {
        pushMatrix();
        translate(width/2, height/2);
        image(carte, xInit, yInit);
    

    ///demarre is for the very beginning but i ll change that

     }
      else {
    
    
    
        image(carte, xInit, yInit);
        popMatrix();
    
      }
    
    //println(mouseX);
    

    /// translating pix into lat or long with map

    double positionL = map(posX,0f, 480F, minW,maxW);
    println (positionL);
    }
    
    void mousePressed() {
      xDeplace = (mouseX-xInit);
      yDeplace = (mouseY-yInit);
      posX = mouseX;
      posY = mouseY;
    }
    
    void mouseDragged() {//is it useful for me i dont think but...
      bouge = true;
      demarre = false;
      xInit= mouseX-xDeplace;
      yInit = mouseY - yDeplace;
    }
    
    void mouseReleased() {
    
      bouge = false;
    }
    
    void onClickWidget(PWidget widget) {///zoom + or zoom-
    
      if (widget == button1) { //bouton +
        if (zoomL<19) {
          zoomL = zoomL+1;
          //TOdO MAXw +, MINw, etc///necessary to change the bounds/zoom
    
          String adresse =  "http://maps.googleapis.com/maps/api/staticmap?center="+lat+","+lon +"&zoom="+zoomL+"&size=960x1600&scale=2&maptype=hybrid&markers=color:blue%7Clabel:S%7C"+lat+","+lon +"&markers=color:green%7Clabel:G%7C40.711614,-74.012318&markers=color:red%7Clabel:C%7C40.718217,-73.998284&sensor=false";
    
          carte = loadImage(adresse);
        }
      }
      else if (widget == button2) { //or if it was button2
        println("moins");
        if (zoomL>= 8) {
          zoomL = zoomL-1;
          //toDo minW=; mawW=...
          String adresse = "http://maps.googleapis.com/maps/api/staticmap?center="+lat+","+lon +"&zoom="+zoomL+"&size=960x1600&scale=2&maptype=hybrid&markers=color:blue%7Clabel:S%7C"+lat+","+lon +"&markers=color:green%7Clabel:G%7C40.711614,-74.012318&markers=color:red%7Clabel:C%7C40.718217,-73.998284&sensor=false";
    
          carte = loadImage(adresse);
        }
      }
    }
    

    ///if somebody tries it, tell me, thanks!

  • Dear Akenaton the problem is google because it blocks my IP after some request

  • dear Camperos,

    As for me it does not block; perhaps because i have got a key on their site (and add it in the manifest file)??? - try to get one...But the best solution would be to use openSreetMaps, what i am unable to do, though knowing the exact url for the lat and long of the map (see above the code i have written for getting that). So i continue with googleMaps...In this moment i have found a new problem (which i thought easy to solve!!!) ::: when you "transform" pixels to lat or long with mapping, the values are not really exact. Till you dont zoom, that does not matter, but in my app i have to zoom in at least at level 17, or 18 (20 is the max i believe) and at zoom level 18 the little differences in the values become very important. Is it necessary to use some mercator projection to be absolutely precise???- As i have to work with "little map" (map of corsica ) i think that mercator is not necessary. but perhaps i am wrong!

    I must tell you that i do know java (and had a look to android APIS) but with processing android mode i am a new bye. Example: in java mode the width of the display is what you announce in the setup() but is it the same with android mode??? the 4 zones right left bottom and top are they included or not??? - As for mapping with mouseEvents that is important to know. If you can tell me, thank in advance!

    best wishes

Sign In or Register to comment.