Error message

Deprecated function: implode(): Passing glue string after array is deprecated. Swap the parameters in drupal_get_feeds() (line 394 of /home1/tylerfra/public_html/includes/common.inc).

Build a Mobile App to Geo Tag a Photo

Category: 

In this tutorial we'll explore how to build a mobile application that can take a photograph and save it onto a website with the current latitude and longitude coordinates.

The website will be powered by Drupal 7. The mobile application will be built using DrupalGap, which is powered by PhoneGapjQuery Mobile and Drupal Services.

Did I mention all of this can be accomplished by writing zero lines of code? Well then, let's get started!

1. Download and Install Drupal 7

2. Download and Install the DrupalGap Module

3. Download and Install the Geofield Module

4. Create a Content Type with an Image Field

By default, Drupal comes with the "Article" content type, and it already has an Image Field. For simplicity we'll use the "Article" content type throughout the tutorial. Feel free to create a custom content type and image field for your needs.

5. Add a Geofield to the Content Type

In Drupal, go to admin/structure/types/manage/article/fields and add a new field with these values:

  • Label: Position
  • Machine Name: field_position
  • Field Type: Geofield
  • Widget: Latitude / Longitude

Click the "Save" button, then click the "Save field settings" button, and finally click the "Save settings" button at the bottom of the form. We'll just use all the default values provided for this tutorial, but feel free to adjust them.

6. Download and Install the DrupalGap Mobile Application Development Kit

Note, at the time of writing this, the development snapshot needs to be downloaded.

During the installation process, it is recommended to use a mobile device with Option 2 when setting up the PhoneGap environment. This will allow you to compile the app directly to your device. Chances are your mobile device has a camera and GPS features. Alternatively, you may use Ripple or an emulator/simulator to build the app, but they may or may not have camera and GPS features, depending on your system's setup.

7. Add the DrupalGap Geofield Module to the Mobile App

Download the Geofield module for DrupalGap, and add it to your app's settings.js file:

Drupal.modules.contrib['geofield'] = {};

8. Run the Mobile Application

Once the app loads, it should look something like this:

9. Login with the App to the Drupal Website

10. Create an Article with an Image and Geo Tag it

After logging in, click the "Content" button to go to the "node/add" page. Here you'll see a list of Content Types you have permission to create, the app page will look something like this:

Click the "article" button to go to the node creation form (node/add/article). Use this form to fill in the Title of your Article, and then either press the "Take Photo" to snap a new picture, or press the "Browse" button to locate an image on your device.

As you scroll down the form, you'll be presented with the Geofield input as well. Make sure your device's GPS feature is enabled, then press the "Get current position" button to have your coordinates auto filled in the form fields:

11. Save the Article with the Image and Coordinates

Finally, click the "Save" button to have your image automatically uploaded to the server and attached to the Article node with the latitutude and longitude coordinates.

12. Conclusion

This tutorial shows how easy it is to build a mobile app to geo tag an image. We really didn't have to write any of our own custom code to make this happen.

DrupalGap is an open source mobile application development kit, so it can be totally customized to meet your needs. This was just a demonstration of "out-of-the-box" features available for DrupalGap.

A big thank you goes out to all of the tools that made this possible:

  • Drupal 7
  • PhoneGap
  • jQueryMobile
  • Drupal Services Module
  • Drupal Geofield Module

Enjoy!

Comments

This a great! Thanks so much for this and all the screenshots.

One link went missing (in that it became bold text rather than a hyperlink):

development snapshot needs to be downloaded."

Do you refer to the dev snapshot of the "DrupalGap Mobile App Dev Kit"?

 

tyler's picture

Thanks, I've updated the text to point to the development snapshot of the mobile app dev kit: https://github.com/signalpoint/DrupalGap/archive/7.x-1.x-alpha.zip

Hi I tried this out but the geolocations are not saving on the node.  . i was wondering how to go about troubleshooting this ?

tyler's picture

Just yesterday I created a debug information page:

http://www.drupalgap.org/node/211

Or stop by the support page for other topics, and we'll be able to figure out what is going on:

http://www.drupalgap.org/support

Be sure to use the latest development snapshot of the SDK.

Hello frankie...

Great work !!!. I'm using your module but I seem to have some issues with storing the coordinates as I only get null values.

 I tried to make some changes and I got some debuging feedback but the variables are not to be understood as numeric values. If I declare them manually from within the code as numbers (e.g. "lat": "23", "lon": "23" ) then everything is stored OK. the issue is that I need some your advise in the coordinate variables to use.

tyler's picture

Hi Andreas,

I'm not sure I understand your issue correctly. But it sounds like it is related to George's comment below, please refer to that info provided there. Or please submit an issue in one of the issue queues and we can properly debug it.

Hello,

Very useful module. I have the same issue mentioned: the location is not getting saved to the node (the widget is lan/lon). I read somewhere that you must include the key "geom" before the coordinate, but I am not sure how to include that to the code.

tyler's picture

Hi George,

It's possible that what must be POSTed has changed in format since I posted this article.

The geofield_assemble_form_state_into_field() function is in charge of assembling the JSON that will be POSTed to the Drupal site. Try setting Drupal.settings.debug value to true in the settings.js file. Then you can watch the data that is POSTed, then modify the geofield_assemble_form_state_into_field() function to assemble the JSON in a new format.

Here's the function: https://github.com/signalpoint/geofield/blob/7.x-1.x/geofield.js#L135

Please let me know how it goes, thanks!

Tyler, thank you for the quick answer.

I changed the code so the geofield_assemble_form_state_into_field() recieves a key

removed: field_key.use_key = false;

with:

field_key.value = 'geom';

From the debug I get:

09-10 02:06:49.415: I/Web Console(9352): {"node":{"nid":"15","title":"test","type":"test_drupal_gap","language":"und","body":{"und":[{"value":"Tedt"}]},"field_main_image":{"und":[{"fid":"84"}]},"field_position":{"und":[{"geom":{"lat":""}}]}}} at file:///android_asset/www/jdrupal-dev.min.js:31

and an alert that longtitude is missing (as it seems from the debuggin).

It seems that now it posts in the right format (with the geom key) but I dont get any values after lat. Maybe I missed sth else somewhere.
 

tyler's picture

Nicely done. Ok, now try to use this line of code as the first line in the geofield_assemble_form_state_into_field() function:

dpm(form_state_value);

That'll output to the console what form state value has been captured and fed to this function. What does that report in the console.log(); ?

It may be best to continue this conversation in #drupal-drupalgap on IRC.

Hello Tyler,

So I did some testing with the dpm command. I tried to add some text before the form state value (like dpm('text'+form_state_value);) and only the text displays in the debug log.

Does that mean tha the form_state_value is empty? It would make sense because if i put lat and lon manually in the code everything works fine. Maybe the textfields with lat and lon are not getting parsed correctly or sth like that?

tyler's picture

Yes, it sounds like the DrupalGap's core Form API isn't properly grabbing the input from the field. Or (even more likely) the Geofield's _geofield_field_widget_form_change() function isn't properly grabbing the input from the two text fields, and setting their combined values (separated by comma) into a single hideen form input. Try doing some debugging in that function to see if it is properly grabbing, and setting values.

Hello again Tyler,

I did more debugging and i think I found the issue.

What happens is that if i change the values manually after i get the position the location is stored normally. If i dont edit them it seems like the method is not running at all. So i m not sure if the problem is inside the method _geofield_field_widget_form_change().

Doing some more testing till I get your answer.

tyler's picture

Interesting. Ok this make more sense. So it sounds like once the position is retrieved by GPS and placed into the text fields automatically, the _geofield_field_widget_form_change() isn't firing, hence the hidden input value never gets set, and then upon submission it appears empty.

Maybe try putting a call to _geofield_field_widget_form_change() inside of _geofield_field_widget_form_click(), e.g.:

function(position) {
  $('#' + lat_id).val(position.coords.latitude);
  $('#' + lon_id).val(position.coords.longitude);
  _geofield_field_widget_form_change();
},

It sounds like the Android emulator (and maybe some Android devices) don't respond correctly to the fields chaning in value, so we probably can get away with the manual call.

Unfortunately it didnt work.

I ll try to put the call in other places and see what happens. I dont know javascript, but could this has anything to do with the execution time of the methods?

One more observation, if I edit the textfield and do whatever changes but I finally return it to its original value, it is not getting saved aswell. The only way to store the location is to add or remove one or more digits from the textfield.

tyler's picture

This is very strange... try putting an e.g.

drupalgap_alert('changing...');

at the top of _geofield_field_widget_form_change() and see when/if that gets fired depending on your various interactiosn. I think we should continue this conversation in the issue queue (we'll need a new issue created): https://github.com/signalpoint/geofield/issues

I found a solution to my problem.

It is posted to the issues of the geofield module: https://github.com/signalpoint/geofield/issues

tyler's picture

Thanks George, I've added your fix to the module!

Hi,

I tried to build app for geo tag photo but geo location could not save on the node. I hope by follwing your steps i can completely solve this issue.

 

Hi tyler, thanks for the tutorials; Images have been upoaded successfully but there are issues attaching an image to a node; The images on my drupal 7 installation are managed with Media module and file entity and I use the code below(updating node with image fid) to attach the images to nodes

$.ajax({
        url: localStorage.appurl+"/api/node/" + encodeURIComponent(nid) + ".json",
        type: 'put',
        data: "field_ftritem_images[und][0][fid]=250&field_ftritem_date_visited[und][0][value][date]=02/10/2015",
        dataType: 'json',
        headers: {
          'X-CSRF-Token': localStorage.usertoken
        },
        error: function(XMLHttpRequest, textStatus, errorThrown) {
          console.log(JSON.stringify(XMLHttpRequest));
          console.log(JSON.stringify(textStatus));
          console.log(JSON.stringify(errorThrown));
 
        },
        success: function (data) {
          
          console.log("We have updated the node ");
        }
      });
 
The ajax call is successfull but the images are not attached to the node.
 
 
tyler's picture

Hi David, first use the Drupal UI to build a typical node that you are trying to create. Then use a GET on said node via ?q=api/node/123.json, and use jsonlint.com to inspect its results. Take a look at how the media module assembles the data for your field. Your PUT/POST requests will most likely match that pattern. What does the data of an image field look like when the media module is in use?

Hi Tyler,

I followed your article and everything works great except that the image doesn't show in node view (it's showing in node edit and on website - mean the node is created and the image is stored successfully). In the XCode console log, it's saying "WARNING: theme_undefined() does not exist. Called by: drupalgap_render_page().". Do you have any ideas how to fix it please?

Thanks in advance!

getting error

geofield_map_field_formatter_view_pageshow - ReferenceError: google is not defined

tyler's picture

You need to include the Google Maps JS file in your index.html file: http://drupalgap.org/node/497

hi, i am using your examples to learn how to use phonegap with drupal and you have done an excellent job so far! Congratulations.

I have only one small question. When i use the path /mobile-application on a desktop browser the buttons of login / content are visible but when i try to use the app from a localhost path e.g 192.168.1.5./dgap/mobile-application the buttons are gone. I have found the option at app/settings.js file on how to switch from web-app / phonegapbut nothing changed

// DrupalGap Mode (defaults to 'web-app')
//  'web-app' - use this mode to build a web application for a browser window
//  'phonegap' - use this mode to build a mobile application with phonegap
drupalgap.settings.mode = 'web-app';

Cordova in Chrome works fine too but, I want to be able to test the mobile version of the app because it is important to test GPS functionality and the camera or microphone access direct from smartphone and not through a simulation. GPS exact location is important for my app. As you can see  at pixelthis.gr/dgap_issue/3.png when i access the 192.168.1.5./dgap/mobile-application path from ios / safari browser my smartphone actually no buttons are shown there. Is this normal? I mean this is why i have to build an app and not access it from a browser :) Sorry if this is a noob question but i am just in the process of learning the drupalgap process/method :)

pixelthis.gr/dgap_issue/1.png

pixelthis.gr/dgap_issue/2.png

pixelthis.gr/dgap_issue/3.png

pixelthis.gr/dgap_issue/4.png

 

 

tyler's picture

You need to include the cordova.js file in the body of your index.html file. You also need to copy the cordova.js to live in the app's www directory from the corresponding platform_www directory provided by cordova.

Working on developing a site that will allow pinning photos on a world map. At some point will need to provide mobile apps to subscribers (Apple and Android, possibly tablets as well) to help them download photos directly to site, and geotag. As I am not an expert, my (silly) question is: can those apps be built around your concept, and offred to subscribers to use?

tyler's picture

Definitely.

Thanks for the prompt reply, Tyler. My next question: is it possible, using you consept and Drupam modules, to geotag to a level "city", "town", "village", etc.? This will be necessary for privacy reasons, as some users of the site I am designing may not wish to geotag exact location of their residence. Thanks in advance.

tyler's picture

Yes, the Address Field module is what you'll want to use to collect generic address information (city, state, zip). If you want more precise coordinate tracking, use the Geofield module. The address field module also lets you optionally collect address 1 and address 2 fields for their street/apt address.

Just to clarify me previous question. Do Drupal modules allow geotagging at level "city/town/village", and not the precise co-ordinates within a city/town/village/etc,? Some users may not wish to geotag the exact co-orinates of some photos (that may be the co-ordinates of their residen.ce). Thanks you