Tech Stuff

Mapping a Map Migration

Why?

Principles, I guess. Google Maps is changing their pricing structure this week so that you have to put in a credit card number. Well, not really as severe as that; but if you want to make sure you don’t get cut off at some point during a busy month, you have to put in a credit card number. And typically the documentation is obscure and the process you have to go through is obfuscated.

This site and its traffic? Phhht. Never gonna get that much traffic. But still, every time somebody on this site opened a Google Maps was another opportunity for that somebody to click on a featured spot and gin up some Google Ad Sense dollars.

So I thought, what does it take to change all the maps from one platform to another? Have I sunk so much time (this blog has been running since 2006) into the Google platform that there’s no going back now?

Well Let’s See

I’m starting from two different Google Map plugins, Comprehensive Google Maps and … I cannot even remember. It might have been Google Maps for WordPress. I just know it used a shortcode that started googleMap… and used an open and close square-bracket syntax.

The first step to changing a bunch of these:

[ google-map-v3 width=”450″ height=”350″ zoom=”12″ maptype=”roadmap” mapalign=”center” directionhint=”false” language=”default” poweredby=”false” maptypecontrol=”true” pancontrol=”true” zoomcontrol=”true” scalecontrol=”true” streetviewcontrol=”true” scrollwheelcontrol=”false” draggable=”true” tiltfourtyfive=”false” addmarkermashupbubble=”false” addmarkermashupbubble=”false” addmarkerlist=”53 Hanover Avenue, Whippany, NJ{}forest2.png{}Frelinghuysen Arboretum” bubbleautopan=”true” showbike=”false” showtraffic=”false” showpanoramio=”false”]

I need a shortcode on the page, because I’m trying to do a global find/replace. Adding the maps by ID into the database is too hard, because then I’d have to manually alter every post. Let’s browse through the few plugins that support something other then Google Maps.

Leaflet Map

We install, activate, and use the default values. Set default geocoder to OpenStreetMapNominatim.

[ leaflet-map zoom=14 address=”Oslo, Norway” scrollwheel=1]
[ leaflet-map zoom=14 address=”carrer del duc, barcelona, spain” scrollwheel=1]
[ leaflet-map zoom=14 lat=43.65 lng=-79.385]
[ leaflet-map zoom=14 address=”whippany, New Jersey” scrollwheel=1]

Whichever version I tried, I got the same map — of Halifax, Nova Scotia. I think that’s the default lat/long of the plugin. Only the explicit latitude and longitude — example 3 –worked. But I was trying to get away from having to look up the lat/long of every single map on my site. Here they are, as generated by the four shortcodes above.

In all fairness, the developer is very responsive and is trying to figure it out. He thinks it might be that Nominatim has changed something.

Leaflet Maps Marker

Install, activate, try a shortcode.

[ mapsmarker lat=”48.216038″ lon=”16.378984″ popuptext=”enter popuptext here” basemap=”mapquest_osm” zoom=”16″ openpopup=”1″ mapwidth=”450″ mapwidthunit=”px” mapheight=”400″ ]

“Loading map, please wait.” And wait, and wait.

I tried everything in their help pages — moving scripts to the headers, disabling plugins, using a default theme. Nothing worked. At this point, it’s too difficult and not worth the effort.

That and it makes your dashboard really gaudy, packed with social media icons and upgrade-to-pro prompts.

Oi Yandex.Maps

Oi indeed. Everything is in Russian. You’ll forgive me if I don’t trust these people.

WP Google Maps

Seemed promising but free version only allows one map per site. Terrific if that’s all you need — a map that shows your office or the like. I’m using the maps more as a travel documentary, so I want to show different places for different posts.

Live map from www.broadwaybach.org

OSM

Full featured, decent shortcode support, only lat/long are really needed.

Can we convert:
[ google-map-v3 shortcodeid=”aa4cd6ef” width=”350″ height=”350″ zoom=”12″ maptype=”roadmap” mapalign=”center” directionhint=”false” language=”default” poweredby=”false” maptypecontrol=”true” pancontrol=”true” zoomcontrol=”true” scalecontrol=”true” streetviewcontrol=”true” scrollwheelcontrol=”false” draggable=”true” tiltfourtyfive=”false” enablegeolocationmarker=”false” enablemarkerclustering=”false” addmarkermashup=”false” addmarkermashupbubble=”false” addmarkerlist=”40.726694, -74.305008{}bed_breakfast1-2.png{}South Mountain Reservation, Millburn Entrance” bubbleautopan=”true” distanceunits=”miles” showbike=”false” showtraffic=”false” showpanoramio=”false”]

Into:
[ osm_map map_center
=”40.726694,-74.305008″ marker=”40.726694,-74.305008,OSM_marker_text” Lat=”40.726694″ Long=”-74.305008″ width=”100%” height=”450″ map_border=”solid thin black” zoom=”12″ marker_name=”wpttemp-red.png” marker_file=”https://tom-mcgee.com/wp-content/plugins/osm/icons/wpttemp-red.png”]

?

(The above is a live map. Here is a screen cap…just in case)

Screen cap of live OSM.

The OSM Wiki is pretty good (https://wiki.openstreetmap.org/wiki/Wordpress), but isn’t exhaustive. Some experimentation is going to be needed…

Adding a title to the pin can only be done by adding a custom field to each individual post. This is fine if you’ve only got one map per page, and feel like editing every one of them. I can’t guarantee that. For this post you’re now reading I added that custom field. But the balloons are pretty ugly anyway. I could clean them up with CSS to tighten up the leading, but then I’ve got two jobs to do. I’m going to omit it and replace it with a caption.

By this point, manually altering every post seems like a good idea. I’m going to go with it.

Toolbox

  • SearchRegex WordPress Plugin
  • Sublime Text 3
  • Open Office Calc
  • Microsoft Excel

SearchRegex

I love this plugin. Search for “|\[google-map-v3.*|,” which is used in the shortcodes for Comprehensive Google Map. I can copy-and-paste the results into Sublime Text 3 and get enough to work with there. For example:

[google-map-v3 width="450" height="350" zoom="12" maptype="roadmap" mapalign="center" directionhint="false" language="default" poweredby="false" maptypecontrol="true" pancontrol="true" zoomcontrol="true" scalecontrol="true" streetviewcontrol="true" scrollwheelcontrol="false" draggable="true" tiltfourtyfive="false" addmarkermashupbubble="false" addmarkermashupbubble="false" addmarkerlist="53 Hanover Avenue, Whippany, NJ{}forest2.png{}Frelinghuysen Arboretum" bubbleautopan="true" showbike="false" showtraffic="false" showpanoramio="false"]

An older plugin I used had a shortcode “[ googleMap …]Address[/googleMap].” SearchRegex found 62 instances like this:

[googleMap name="New Providence, NJ" width="475" height="300" description="More or less around here. It was somewhere on Rt. 512."]Springfield Ave., New Providence, NJ[/googleMap]

Using Sublime’s regular expression find-and-replace I can cut these down to size.

view | edit Post #\d+:.*

Replace with “” (nothing).

^[^[]*\[google-map

Anything at the beginning of a line that’s not an open-bracket.
Replace with “[google-map”. This limits it to the newer plugin’s style.

^(\[google-map-v3[^]]*]).*

Replace with $1. This only keeps the shortcode.

Then, we need to isolate the place names — addresses or geo-coordinates. We’re going to search for them by their bracketed name in the shortcode, “addmarkerlist.” Those have some additional fields, separated by curly brackets, so we will stop before we get to them.

(\[google-map-v3.*addmarkerlist="([^{"]*).*)

Replace with $1\t$2. This puts a tab between the shortcode and the place location, so we can open it later into Excel. A line will look like this:

[google-map-v3 shortcodeid=”c884703a” width=”450″ height=”350″ zoom=”12″ maptype=”roadmap” mapalign=”center” directionhint=”false” language=”default” poweredby=”false” maptypecontrol=”true” pancontrol=”true” zoomcontrol=”true” scalecontrol=”true” streetviewcontrol=”true” scrollwheelcontrol=”false” draggable=”true” tiltfourtyfive=”false” enablegeolocationmarker=”false” enablemarkerclustering=”false” addmarkermashup=”false” addmarkermashupbubble=”false” addmarkerlist=”1000 Mountain Rest Road, New Paltz, NY{}cabin-2.png{}Mohonk Mountain House” bubbleautopan=”true” distanceunits=”miles” showbike=”false” showtraffic=”false” showpanoramio=”false”](tab character here!)1000 Mountain Rest Road, New Paltz, NY

Next we’ll tackle the old-style tags from a previous plugin. These went [googleMap (params)]address[/googleMap]. So it should be simple to grab the inner address and reproduce it after a tab.

^[^[]*(\[googleMap[^]]*]([^[]*)\[/googleMap]).*

Replace with $1\t$2.

Similar...  WP-CLI, Just For Multisite Fun

When I save this into a CSV file, and open it into Open Office Calc, it’s pretty clean. There was one line that needed manual intervention, a column to delete with duplicate data, and a few lines that were malformed because of the way the original search results were returned. No big deal.

Next, GeoCoordinates

Now I back it into Excel again, to use some of that application’s functions. Open Office has a function to import a data set from a URL, but I couldn’t get it to work; I think it only “goes” if your URL has a table from which it can read rows and columns, and you can’t really insert it into a cell for further work. But Excel has two spiffy functions, WEBSERVICE and FILTERXML.

I’ll add four columns to my spreadsheet. In the top cell of the first, I insert:

=WEBSERVICE(CONCATENATE("http://nominatim.openstreetmap.org/search/?format=xml&q=",B1))

Where cell B1 holds the first address.
This returns a chunk of XML code that looks like this (line feeds and indents added for readability):

<?xml version=""1.0"" encoding=""UTF-8"" ?>
<searchresults
   timestamp='Mon, 11 Jun 18 16:06:34 +0000'
   attribution='Data © OpenStreetMap contributors, ODbL 1.0. http://www.openstreetmap.org/copyright'
   querystring='1135 Ocean Avenue, Sea Bright, New Jersey'
   polygon='false'
   exclude_place_ids='202173991'
   more_url='https://nominatim.openstreetmap.org/search.php?q=1135+Ocean+Avenue%2C+Sea+Bright%2C+New+Jersey&amp;exclude_place_ids=202173991&amp;format=xml'>
<place
   place_id='202173991'
   osm_type='way'
   osm_id='11698177'
   place_rank='30'
   boundingbox=""40.360768653488,40.360868653488,-73.974287773328,-73.974187773328""
   lat='40.360818653488'
   lon='-73.9742377733279'
   display_name='1135, Ocean Avenue, Sea Bright, Monmouth County, New Jersey, 07760, United States of America'
   class='place'
   type='house'
   importance='0.71025'/>
</searchresults>

There’s a lot we can pull out of this, but we’re going to limit it to the lat, lon and display_name fields. You could probably pull out the “type” and use it to build a URL for a custom icon.

In the second, third and fourth, insert:

=FILTERXML(C83,"//place/@lat")
=FILTERXML(C83,"//place/@lon")
=FILTERXML(C83,"//place/@display_name")

The nice thing here is, the web service responds with pretty full descriptions of the place. Even where I had to settle for feeding latitude and longitude into the location cell (eg, “41.387696,2.175176”) it gives me “Palau de la Música, 4-6, Carrer del Palau de la Música, Sant Pere, Santa Caterina i la Ribera, Ciutat Vella, Barcelona, BCN, CAT, 08003, España”.

But the locator is pretty picky. It will often accept street addresses, but they have to be just so. Sometimes it will accept a place name (“Thomas Edison National Historic Park”) while rejecting the corresponding address (on Main Street in West Orange.) Sometimes vice-versa.

New York street addresses have to use “W.” or “E.”, and you must use the “3rd” or “4th” ordinal form. It will accept intersections, but the street names have to be separated with an ampersand, not “and.” But with the spreadsheet active, I could massage the names a little until the “#VALUE” error went away.

Are We Tired Of This Yet?

It’s almost as convoluted as setting up your payment plan! If I had WP-CLI available on this host I would have been all over it by now. It’s a perfect job for a script. It would also streamline added the custom field “OSM_marker_text.” Oh well.

But now I have a list of old shortcodes in the first column, and all the information I need to create a new shortcode in the last. And for that I’ll fall back on the venerable “=CONCATENATE” function. Again, line feeds added.

=CONCATENATE("<figure>[osm_map map_center=""",
  D1,",",E1,""" marker=""",D1,",",E1,"""
  Lat=""",D1,""", Long=""",E1,""" width=""100%"" height=""450""
  map_border=""solid thin black"" zoom=""12""
  marker_name=""wpttemp-red.png""
  marker_file=""https://tom-mcgee.com/wp-content/plugins/osm/icons/wpttemp-red.png""]
<figcaption>",F1,"</figcaption></figure>")

Which to make a long story short generates:

<figure>[osm_map
  map_center="40.80213565,-74.4557472796711"  
  marker="40.80213565,-74.4557472796711"  
  Lat="40.80213565" Long="-74.4557472796711" width="100%" height="450"  
  map_border="solid thin black" zoom="12"  
  marker_name="wpttemp-red.png"
  marker_file="https://tom-mcgee.com/wp-content/plugins/osm/icons/wpttemp-red.png"]
<figcaption>Frelinghuysen Arboretum, I 287, Morristown, Morris County, New Jersey, 07927, United States of America</figcaption></figure>
Frelinghuysen Arboretum, I 287, Morristown, Morris County, New Jersey, 07927, United States of America

I’m coding these as a figure with a figcaption inside. Originally I was going to run a header underneath, but this is more semantically correct.

83 Maps?

Did I mention how I wish I had access to WP-CLI on this host?

Next we’ll try a dry run of a few of these. We’ll use the SearchRegEx plugin, but with regular expressions turned off. One row at a time, I’ll search for the pre-existing map code block, and swap it out for the new code block.

As always with this plugin, do a dry run first by clicking the “Replace” button only. If it makes sense, only then click the “Replace and Save” button.

I did the first one, for the Freylinghuysen Arboretum. The next one is

Jersey Shore Damage Tour

This had three of the google-map-v3 shortcodes. All were changed correctly.

And one post from our trip to Spain, with a more complicated European address, came out fine as well.

Esglesia de Sant Pau del Camp

Working with the older plugin, which uses the googleMap syntax, I updated this post:

Capital Crescent Trail

Other Options

Bing Maps

The first one isn’t really an option. You can try embedding a Bing map. Bing (apparently) doesn’t support oEmbed, so you have to use their iframe embedder. Here’s an example:

What’s interesting about this is I searched for a specific address and it’s not showing up here. It’s within the boundaries of the map, but it’s not centered and it’s not marked.

Google Maps

Yeah, I know. But in the interest of thoroughness. When I went for an embed code it warned me that if I embedded this on my web site only I would see it; other visitors would see a map just for them. Whatever that means, it doesn’t sound like what I want.

Open Street Maps


View Larger Map

This works, and it’s not too bad. I can get a marker, and it’s centered. I can also adjust the size.

MapQuest

The original, still kicking after all these years. And not bad, either.

To Sum Up

This was a lot of work for not a lot of results. I only had 83 maps, and it would have taken less time to do each post by hand. If I had several hundred to update though, I would write a Perl script running CLI to do all the finds/replaces for me. It could have also updated the custom field. And I’m only halfway through working down the list

But, in principle, I’m glad I’m doing this. As vendors become more and more proprietary, and the web turns into a set of walled gardens like the bad old days of Compuserve and AOL, those of us who are maintaining our own identity and keeping control of our own content need to have tools and skills to keep it that way.

Leave a Reply

Your email address will not be published. Required fields are marked *