From c1ef06bbbe364d8669eb9cd42146e6cf1952492a Mon Sep 17 00:00:00 2001
From: Demian Katz <demian.katz@villanova.edu>
Date: Wed, 21 Jun 2017 09:26:28 -0400
Subject: [PATCH] Remove Google Maps code. (#995)

---
 config/vufind/config.ini                      |   8 +-
 config/vufind/searches.ini                    |   9 -
 .../src/org/vufind/index/GeoTools.java        |  77 -------
 import/marc_local.properties                  |   3 +-
 module/VuFind/config/module.config.php        |   2 +-
 module/VuFind/src/VuFind/Config/Upgrade.php   |  10 +
 .../src/VuFind/Controller/AjaxController.php  |  65 ------
 .../VuFind/src/VuFind/Recommend/Factory.php   |  15 --
 .../src/VuFind/Recommend/MapSelection.php     |  14 --
 .../VuFind/Recommend/ResultGoogleMapAjax.php  | 133 ------------
 .../src/VuFind/RecordDriver/SolrDefault.php   |  11 -
 .../VuFind/src/VuFind/RecordTab/Factory.php   |   4 +-
 module/VuFind/src/VuFind/RecordTab/Map.php    |  57 +----
 .../configs/googlewarnings/config.ini         |   6 +-
 .../src/VuFindTest/Config/UpgradeTest.php     |  12 +
 solr/vufind/biblio/conf/schema.xml            |   2 -
 tests/data/geo.mrc.properties                 |   1 -
 .../Recommend/ResultGoogleMapAjax.phtml       | 205 ------------------
 .../bootstrap3/templates/RecordTab/map.phtml  |  66 +-----
 19 files changed, 33 insertions(+), 667 deletions(-)
 delete mode 100644 module/VuFind/src/VuFind/Recommend/ResultGoogleMapAjax.php
 delete mode 100644 themes/bootstrap3/templates/Recommend/ResultGoogleMapAjax.phtml

diff --git a/config/vufind/config.ini b/config/vufind/config.ini
index c94b435a6a8..81f6a00ce92 100644
--- a/config/vufind/config.ini
+++ b/config/vufind/config.ini
@@ -747,8 +747,7 @@ authors         = Wikipedia
 ;europeanaAPI = INSERTKEY
 
 ; Geographic Display
-; recordMap can be set to either 'google' or 'openlayers';
-; 'google' will only display point features
+; recordMap can be set to 'openlayers';
 ; 'openlayers' will display point and rectangle features. Default setting
 ; (see import/marc_local.properties for more information).
 ; Map Tab Options:
@@ -770,11 +769,6 @@ authors         = Wikipedia
 ;mapLabels = file:geosearch_test_lookup.txt
 ;displayCoords = true
 
-; If you set recordMap = google, then Google requires that you obtain an API key.
-; For more information on obtaining an API key, see:
-; https://developers.google.com/maps/documentation/javascript/get-api-key#key
-;googleMapApiKey = "your-key-here"
-
 ; This section controls the behavior of the cover generator when makeDynamicCovers
 ; above is non-false.
 ;
diff --git a/config/vufind/searches.ini b/config/vufind/searches.ini
index 82b18f184f1..5008b585526 100644
--- a/config/vufind/searches.ini
+++ b/config/vufind/searches.ini
@@ -340,15 +340,6 @@ CallNumber = callnumber-sort
 ;       fields.  This is designed for a field containing four-digit years.  Zooming
 ;       is set to either true or false and controls whether or not selecting part of
 ;       the graph zooms in to greater detail.
-; ResultGoogleMapAjax:[facets]
-;       Show a Google Map with markers for all result items which have long/latitude
-;       data (be sure to turn on location indexing in import/marc_local.properties).
-;       Each marker will show the number of items which are in the long_lat
-;       facet. A separate call is made when a marker is clicked to retrieve the
-;       first 5 records on that location facet. The map uses clustering to
-;       combine markers where there are more than one marker close together into
-;       clusters. The facets parameter is the name of the extra config file which
-;       holds the facet information(default "facets.ini").
 ; TopFacets:[ini section]:[ini name]
 ;       Display facets listed in the specified section of the specified ini file;
 ;       if [ini name] is left out, it defaults to "facets."
diff --git a/import/index_java/src/org/vufind/index/GeoTools.java b/import/index_java/src/org/vufind/index/GeoTools.java
index 50195e4b5ff..bd34163409f 100644
--- a/import/index_java/src/org/vufind/index/GeoTools.java
+++ b/import/index_java/src/org/vufind/index/GeoTools.java
@@ -8,7 +8,6 @@ package org.vufind.index;
  *
  * code adapted from xrosecky - Moravian Library
  * https://github.com/moravianlibrary/VuFind-2.x/blob/master/import/index_scripts/geo.bsh
- * and incorporates legacy VuFind functionality for GoogleMap display.
  *
  * Copyright (C) Villanova University 2017.
  *
@@ -91,36 +90,6 @@ public class GeoTools
         return geo_coordinates;
     }
 
-    /**
-     * Get point coordinates for GoogleMap display.
-     *
-     * @param  Record record
-     * @return List   coordinates
-     */
-    public List<String> getPointCoordinates(Record record) {
-        List<String> coordinates = new ArrayList<String>();
-        List<VariableField> list034 = record.getVariableFields("034");
-        if (list034 != null) {
-            for (VariableField vf : list034) {
-                HashMap<Character, String> coords = getCoordinateValues(vf);
-                // Check for null coordinates
-                if (validateCoordinateValues(record, coords)) {
-                    // Check to see if we have a point coordinate
-                    if (coords.get('d').equals(coords.get('e')) && coords.get('f').equals(coords.get('g'))) {
-                        // Convert N (f_coord) and E (e_coord) coordinates to decimal degrees
-                        Double long_val = convertCoordinate(coords.get('e'));
-                        Double lat_val = convertCoordinate(coords.get('f'));
-                        String longlatCoordinate = Double.toString(long_val) + ',' + Double.toString(lat_val);
-                        coordinates.add(longlatCoordinate);
-                    }
-                } else {
-                    logger.error(".......... Not indexing INVALID Point coordinates: [ {" + coords.get('d') + "} {" + coords.get('e') + "} {" + coords.get('f') + "} {" + coords.get('g') + "} ]");
-                }
-            }
-        }
-        return coordinates;
-    }
-
     /**
      * Get all available coordinates from the record.
      *
@@ -407,50 +376,4 @@ public class GeoTools
         }
         return true;
     }
-
-    /**
-     * THIS FUNCTION HAS BEEN DEPRECATED.
-     * Determine the longitude and latitude of the items location.
-     *
-     * @param  record current MARC record
-     * @return string of form "longitude, latitude"
-     * @deprecated
-     */
-    public String getLongLat(Record record) {
-        // Check 034 subfield d and f
-        List<VariableField> fields = record.getVariableFields("034");
-        Iterator<VariableField> fieldsIter = fields.iterator();
-        if (fields != null) {
-            DataField physical;
-            while(fieldsIter.hasNext()) {
-                physical = (DataField) fieldsIter.next();
-                String val = null;
-
-                List<Subfield> subfields_d = physical.getSubfields('d');
-                Iterator<Subfield> subfieldsIter_d = subfields_d.iterator();
-                if (subfields_d != null) {
-                    while (subfieldsIter_d.hasNext()) {
-                        val = subfieldsIter_d.next().getData().trim();
-                        if (!val.matches("-?\\d+(.\\d+)?")) {
-                            return null;
-                        }
-                    }
-                }
-                List<Subfield> subfields_f = physical.getSubfields('f');
-                Iterator<Subfield> subfieldsIter_f = subfields_f.iterator();
-                if (subfields_f != null) {
-                    while (subfieldsIter_f.hasNext()) {
-                        String val2 = subfieldsIter_f.next().getData().trim();
-                        if (!val2.matches("-?\\d+(.\\d+)?")) {
-                            return null;
-                        }
-                        val = val + ',' + val2;
-                    }
-                }
-                return val;
-            }
-        }
-        //otherwise return null
-        return null;
-    }
 }
\ No newline at end of file
diff --git a/import/marc_local.properties b/import/marc_local.properties
index dcfbe82eb86..614afe80146 100644
--- a/import/marc_local.properties
+++ b/import/marc_local.properties
@@ -28,11 +28,10 @@
 #fulltext = custom, getFulltext(856u, pdf)
 
 # Uncomment the following if you want to use the OpenLayers3 Geographic Search
-# and Google Map or OpenLayers3 Geo-Display functionality
+# and OpenLayers3 Geo-Display functionality
 # See searches.ini for configuration options for Geographic Searching.
 # See config.ini for configuration options for Geo-Display.
 #location_geo = custom, getAllCoordinates
-#long_lat = custom, getPointCoordinates
 #long_lat_display = custom, getDisplayCoordinates
 #long_lat_label = 034z
 
diff --git a/module/VuFind/config/module.config.php b/module/VuFind/config/module.config.php
index 6c9668bbcf7..ad31de6c076 100644
--- a/module/VuFind/config/module.config.php
+++ b/module/VuFind/config/module.config.php
@@ -496,7 +496,6 @@ $config = [
                     'expandfacets' => 'VuFind\Recommend\Factory::getExpandFacets',
                     'favoritefacets' => 'VuFind\Recommend\Factory::getFavoriteFacets',
                     'mapselection' => 'VuFind\Recommend\Factory::getMapSelection',
-                    'resultgooglemapajax' => 'VuFind\Recommend\Factory::getResultGoogleMapAjax',
                     'sidefacets' => 'VuFind\Recommend\Factory::getSideFacets',
                     'randomrecommend' => 'VuFind\Recommend\Factory::getRandomRecommend',
                     'summonbestbets' => 'VuFind\Recommend\Factory::getSummonBestBets',
@@ -520,6 +519,7 @@ $config = [
                     'openlibrarysubjectsdeferred' => 'VuFind\Recommend\OpenLibrarySubjectsDeferred',
                     'pubdatevisajax' => 'VuFind\Recommend\PubDateVisAjax',
                     'removefilters' => 'VuFind\Recommend\RemoveFilters',
+                    'resultgooglemapajax' => 'VuFind\Recommend\Deprecated',
                     'spellingsuggestions' => 'VuFind\Recommend\SpellingSuggestions',
                     'summonbestbetsdeferred' => 'VuFind\Recommend\SummonBestBetsDeferred',
                     'summondatabasesdeferred' => 'VuFind\Recommend\SummonDatabasesDeferred',
diff --git a/module/VuFind/src/VuFind/Config/Upgrade.php b/module/VuFind/src/VuFind/Config/Upgrade.php
index 8e92c1a67f3..f1ebe2ed79f 100644
--- a/module/VuFind/src/VuFind/Config/Upgrade.php
+++ b/module/VuFind/src/VuFind/Config/Upgrade.php
@@ -572,6 +572,16 @@ class Upgrade
                 . 'longer supported due to changes in Google APIs.'
             );
         }
+        if (isset($newConfig['Content']['recordMap'])
+            && 'google' == strtolower($newConfig['Content']['recordMap'])
+        ) {
+            unset($newConfig['Content']['recordMap']);
+            unset($newConfig['Content']['googleMapApiKey']);
+            $this->addWarning(
+                'Google Maps is no longer a supported Content/recordMap option;'
+                . ' please review your config.ini.'
+            );
+        }
         if (isset($newConfig['GoogleAnalytics']['apiKey'])) {
             if (!isset($newConfig['GoogleAnalytics']['universal'])
                 || !$newConfig['GoogleAnalytics']['universal']
diff --git a/module/VuFind/src/VuFind/Controller/AjaxController.php b/module/VuFind/src/VuFind/Controller/AjaxController.php
index de24481c668..2e7a6bdee09 100644
--- a/module/VuFind/src/VuFind/Controller/AjaxController.php
+++ b/module/VuFind/src/VuFind/Controller/AjaxController.php
@@ -815,71 +815,6 @@ class AjaxController extends AbstractBase
         return $this->output($html, self::STATUS_OK);
     }
 
-    /**
-     * Get map data on search results and output in JSON
-     *
-     * @param array $fields Solr fields to retrieve data from
-     *
-     * @author Chris Hallberg <crhallberg@gmail.com>
-     * @author Lutz Biedinger <lutz.biedinger@gmail.com>
-     *
-     * @return \Zend\Http\Response
-     */
-    protected function getMapDataAjax($fields = ['long_lat'])
-    {
-        $this->disableSessionWrites();  // avoid session write timing bug
-        $results = $this->getResultsManager()->get('Solr');
-        $params = $results->getParams();
-        $params->initFromRequest($this->getRequest()->getQuery());
-
-        $facets = $results->getFullFieldFacets($fields, false);
-
-        $markers = [];
-        $i = 0;
-        $list = isset($facets['long_lat']['data']['list'])
-            ? $facets['long_lat']['data']['list'] : [];
-        foreach ($list as $location) {
-            $longLat = explode(',', $location['value']);
-            $markers[$i] = [
-                'title' => (string)$location['count'], //needs to be a string
-                'location_facet' =>
-                    $location['value'], //needed to load in the location
-                'lon' => $longLat[0],
-                'lat' => $longLat[1]
-            ];
-            $i++;
-        }
-        return $this->output($markers, self::STATUS_OK);
-    }
-
-    /**
-     * Get entry information on entries tied to a specific map location
-     *
-     * @author Chris Hallberg <crhallberg@gmail.com>
-     * @author Lutz Biedinger <lutz.biedinger@gmail.com>
-     *
-     * @return mixed
-     */
-    public function resultgooglemapinfoAction()
-    {
-        $this->disableSessionWrites();  // avoid session write timing bug
-        // Set layout to render content only:
-        $this->layout()->setTemplate('layout/lightbox');
-
-        $results = $this->getResultsManager()->get('Solr');
-        $params = $results->getParams();
-        $params->initFromRequest($this->getRequest()->getQuery());
-
-        return $this->createViewModel(
-            [
-                'results' => $results,
-                'recordSet' => $results->getResults(),
-                'recordCount' => $results->getResultTotal(),
-                'completeListUrl' => $results->getUrlQuery()->getParams()
-            ]
-        );
-    }
-
     /**
      * AJAX for timeline feature (PubDateVisAjax)
      *
diff --git a/module/VuFind/src/VuFind/Recommend/Factory.php b/module/VuFind/src/VuFind/Recommend/Factory.php
index 23b56b4aec8..908e115fc76 100644
--- a/module/VuFind/src/VuFind/Recommend/Factory.php
+++ b/module/VuFind/src/VuFind/Recommend/Factory.php
@@ -212,21 +212,6 @@ class Factory
         );
     }
 
-    /**
-     * Factory for ResultGoogleMapAjax Recommendations.
-     *
-     * @param ServiceManager $sm Service manager.
-     *
-     * @return ResultGoogleMapAjax
-     */
-    public static function getResultGoogleMapAjax(ServiceManager $sm)
-    {
-        $config = $sm->getServiceLocator()->get('VuFind\Config')->get('config');
-        $key = isset($config->Content->googleMapApiKey)
-            ? $config->Content->googleMapApiKey : null;
-        return new ResultGoogleMapAjax($key);
-    }
-
     /**
      * Factory for SideFacets module.
      *
diff --git a/module/VuFind/src/VuFind/Recommend/MapSelection.php b/module/VuFind/src/VuFind/Recommend/MapSelection.php
index d22e4e84224..2a202ac9adc 100644
--- a/module/VuFind/src/VuFind/Recommend/MapSelection.php
+++ b/module/VuFind/src/VuFind/Recommend/MapSelection.php
@@ -293,20 +293,6 @@ class MapSelection implements \VuFind\Recommend\RecommendInterface
         return $this->searchParams;
     }
 
-    /**
-     * GetSearchParams no question mark at end
-     *
-     * Return search params without leading question mark and colon.
-     * Copied from ResultGoogleMapAjax.php and chngd name to add NoQ.LMG
-     *
-     * @return string
-     */
-    public function getSearchParamsNoQ()
-    {
-        // Get search parameters and return them minus the leading ?:
-           return substr($this->searchObject->getUrlQuery()->getParams(false), 1);
-    }
-
     /**
      * GetGeoField
      *
diff --git a/module/VuFind/src/VuFind/Recommend/ResultGoogleMapAjax.php b/module/VuFind/src/VuFind/Recommend/ResultGoogleMapAjax.php
deleted file mode 100644
index 833c4f687c8..00000000000
--- a/module/VuFind/src/VuFind/Recommend/ResultGoogleMapAjax.php
+++ /dev/null
@@ -1,133 +0,0 @@
-<?php
-/**
- * AuthorInfo Recommendations Module
- *
- * PHP version 5
- *
- * Copyright (C) Villanova University 2010.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * @category VuFind
- * @package  Recommendations
- * @author   Chris Hallberg <challber@villanova.edu>
- * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @link     https://vufind.org/wiki/development:plugins:recommendation_modules Wiki
- */
-namespace VuFind\Recommend;
-
-/**
- * AuthorInfo Recommendations Module
- *
- * This class gathers information from the Wikipedia API and publishes the results
- * to a module at the top of an author's results page
- *
- * @category VuFind
- * @package  Recommendations
- * @author   Lutz Biedinger <lutz.biedinger@gmail.com>
- * @author   Chris Hallberg <challber@villanova.edu>
- * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @link     https://vufind.org/wiki/development:plugins:recommendation_modules Wiki
- * @view     AuthorInfoFacets.phtml
- */
-class ResultGoogleMapAjax implements RecommendInterface
-{
-    /**
-     * Saved search results
-     *
-     * @var \VuFind\Search\Base\Results
-     */
-    protected $searchObject;
-
-    /**
-     * Google Maps API key.
-     *
-     * @var string
-     */
-    protected $googleMapApiKey;
-
-    /**
-     * Constructor
-     *
-     * @param string $key API key
-     */
-    public function __construct($key)
-    {
-        $this->googleMapApiKey = $key;
-    }
-
-    /**
-     * Store the configuration of the recommendation module.
-     *
-     * @param string $settings Settings from searches.ini.
-     *
-     * @return void
-     */
-    public function setConfig($settings)
-    {
-        // No special settings
-    }
-
-    /**
-     * Called at the end of the Search Params objects' initFromRequest() method.
-     * This method is responsible for setting search parameters needed by the
-     * recommendation module and for reading any existing search parameters that may
-     * be needed.
-     *
-     * @param \VuFind\Search\Base\Params $params  Search parameter object
-     * @param \Zend\StdLib\Parameters    $request Parameter object representing user
-     * request.
-     *
-     * @return void
-     */
-    public function init($params, $request)
-    {
-        // No action needed here.
-    }
-
-    /**
-     * Called after the Search Results object has performed its main search.  This
-     * may be used to extract necessary information from the Search Results object
-     * or to perform completely unrelated processing.
-     *
-     * @param \VuFind\Search\Base\Results $results Search results object
-     *
-     * @return void
-     */
-    public function process($results)
-    {
-        $this->searchObject = $results;
-    }
-
-    /**
-     * Get the Google Maps API key.
-     *
-     * @return string
-     */
-    public function getGoogleMapApiKey()
-    {
-        return $this->googleMapApiKey;
-    }
-
-    /**
-     * Get search parameters
-     *
-     * @return string of params
-     */
-    public function getSearchParams()
-    {
-        // Get search parameters and return them minus the leading ?:
-        return substr($this->searchObject->getUrlQuery()->getParams(false), 1);
-    }
-}
diff --git a/module/VuFind/src/VuFind/RecordDriver/SolrDefault.php b/module/VuFind/src/VuFind/RecordDriver/SolrDefault.php
index 688a6c7d5f1..3331930eb74 100644
--- a/module/VuFind/src/VuFind/RecordDriver/SolrDefault.php
+++ b/module/VuFind/src/VuFind/RecordDriver/SolrDefault.php
@@ -1820,17 +1820,6 @@ class SolrDefault extends AbstractBase
             ? $this->fields['title_sort'] : parent::getSortTitle();
     }
 
-    /**
-     * Get longitude/latitude values (or empty array if not available).
-     *
-     * @return array
-     */
-    public function getLongLat()
-    {
-        return isset($this->fields['long_lat'])
-            ? $this->fields['long_lat'] : [];
-    }
-
     /**
      * Get schema.org type mapping, an array of sub-types of
      * http://schema.org/CreativeWork, defaulting to CreativeWork
diff --git a/module/VuFind/src/VuFind/RecordTab/Factory.php b/module/VuFind/src/VuFind/RecordTab/Factory.php
index f37187e7cc7..b2be0188d60 100644
--- a/module/VuFind/src/VuFind/RecordTab/Factory.php
+++ b/module/VuFind/src/VuFind/RecordTab/Factory.php
@@ -180,9 +180,7 @@ class Factory
         $mapType = isset($config->Content->recordMap)
             ? $config->Content->recordMap : null;
         $options = [];
-        $optionFields = [
-            'displayCoords', 'mapLabels', 'googleMapApiKey'
-        ];
+        $optionFields = ['displayCoords', 'mapLabels'];
         foreach ($optionFields as $field) {
             if (isset($config->Content->$field)) {
                 $options[$field] = $config->Content->$field;
diff --git a/module/VuFind/src/VuFind/RecordTab/Map.php b/module/VuFind/src/VuFind/RecordTab/Map.php
index 1f54c45917e..017e504665e 100644
--- a/module/VuFind/src/VuFind/RecordTab/Map.php
+++ b/module/VuFind/src/VuFind/RecordTab/Map.php
@@ -61,30 +61,16 @@ class Map extends AbstractBase
      */
     protected $mapLabels = null;
 
-    /**
-     * Google Maps API key.
-     *
-     * @var string
-     */
-    protected $googleMapApiKey = null;
-
     /**
      * Constructor
      *
-     * @param string $mapType Map provider (valid options: 'google' or 'openlayers';
+     * @param string $mapType Map provider (valid options: 'openlayers';
      * null to disable this feature)
      * @param array  $options Additional settings
      */
     public function __construct($mapType = null, $options = [])
     {
         switch (trim(strtolower($mapType))) {
-        case 'google':
-            // Confirm API key, then fall through to 'openlayers' case for
-            // other standard behavior:
-            if (empty($options['googleMapApiKey'])) {
-                throw new \Exception('Google API key must be set in config.ini');
-            }
-            $this->googleMapApiKey = $options['googleMapApiKey'];
         case 'openlayers':
             $this->mapType = trim(strtolower($mapType));
             $legalOptions = ['displayCoords', 'mapLabels'];
@@ -128,16 +114,6 @@ class Map extends AbstractBase
         return $this->mapType;
     }
 
-    /**
-     * Get the Google Maps API key.
-     *
-     * @return string
-     */
-    public function getGoogleMapApiKey()
-    {
-        return $this->googleMapApiKey;
-    }
-
     /**
      * Is this tab active?
      *
@@ -148,41 +124,10 @@ class Map extends AbstractBase
         if ($this->mapType == 'openlayers') {
             $geocoords = $this->getRecordDriver()->tryMethod('getGeoLocation');
             return !empty($geocoords);
-        } else if ($this->mapType == 'google') {
-            $longLat = $this->getRecordDriver()->tryMethod('getLongLat');
-            return !empty($longLat);
         }
         return false;
     }
 
-    /**
-     * Get the JSON needed to display the record on a Google map.
-     *
-     * @return string
-     */
-    public function getGoogleMapMarker()
-    {
-        $longLat = $this->getRecordDriver()->tryMethod('getLongLat');
-        if (empty($longLat)) {
-            return json_encode([]);
-        }
-        $markers = [];
-        $mapDisplayLabels = $this->getMapLabels();
-        foreach ($longLat as $key => $value) {
-            $coordval = explode(',', $value);
-            $label = isset($mapDisplayLabels[$key])
-                ? $mapDisplayLabels[$key] : '';
-            $markers[] = [
-                [
-                    'title' => $label,
-                    'lon' => $coordval[0],
-                    'lat' => $coordval[1]
-                ]
-            ];
-        }
-        return json_encode($markers);
-    }
-
     /**
      * Get the bbox-geo coordinates.
      *
diff --git a/module/VuFind/tests/fixtures/configs/googlewarnings/config.ini b/module/VuFind/tests/fixtures/configs/googlewarnings/config.ini
index f459455e30d..62b4d120b4f 100644
--- a/module/VuFind/tests/fixtures/configs/googlewarnings/config.ini
+++ b/module/VuFind/tests/fixtures/configs/googlewarnings/config.ini
@@ -2,4 +2,8 @@
 apiKey = 'fake'
 
 [GoogleSearch]
-fake = fake
\ No newline at end of file
+fake = fake
+
+[Content]
+recordMap = google
+googleMapApiKey = abcd
\ No newline at end of file
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Config/UpgradeTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Config/UpgradeTest.php
index a9e21903bd2..b8562fc06ca 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Config/UpgradeTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Config/UpgradeTest.php
@@ -406,6 +406,18 @@ class UpgradeTest extends \VuFindTest\Unit\TestCase
                 $warnings
             )
         );
+        $this->assertTrue(
+            in_array(
+                'Google Maps is no longer a supported Content/recordMap option;'
+                . ' please review your config.ini.',
+                $warnings
+            )
+        );
+        $results = $upgrader->getNewConfigs();
+        $this->assertFalse(isset($results['config.ini']['Content']['recordMap']));
+        $this->assertFalse(
+            isset($results['config.ini']['Content']['googleMapApiKey'])
+        );
     }
 
     /**
diff --git a/solr/vufind/biblio/conf/schema.xml b/solr/vufind/biblio/conf/schema.xml
index 94c91be5aaf..f218689ed5a 100644
--- a/solr/vufind/biblio/conf/schema.xml
+++ b/solr/vufind/biblio/conf/schema.xml
@@ -190,8 +190,6 @@
    <field name="era_facet" type="textFacet" indexed="true" stored="true" multiValued="true"/>
    <field name="illustrated" type="string" indexed="true" stored="true" multiValued="false"/>
    <!-- Used for geographic map display -->
-   <!-- long_lat only used for Google Maps display of point features -->
-   <field name="long_lat" type="textFacet" indexed="true" stored="true" multiValued="true"/>
    <field name="long_lat_display" type="text" indexed="true" stored="true" multiValued="true"/>
    <field name="long_lat_label" type="string" indexed="false" stored="true" multiValued="true"/>
    <!-- Container fields (i.e. for describing journal containing an article) -->
diff --git a/tests/data/geo.mrc.properties b/tests/data/geo.mrc.properties
index e5d632f91c3..d6ebed82f3f 100644
--- a/tests/data/geo.mrc.properties
+++ b/tests/data/geo.mrc.properties
@@ -1,6 +1,5 @@
 id = 001, (pattern_map.id_prefix), first
 pattern_map.id_prefix.pattern_0 = (.+)=>geo$1
 location_geo = custom, getAllCoordinates
-long_lat = custom, getPointCoordinates
 long_lat_display = custom, getDisplayCoordinates
 long_lat_label = 034z
diff --git a/themes/bootstrap3/templates/Recommend/ResultGoogleMapAjax.phtml b/themes/bootstrap3/templates/Recommend/ResultGoogleMapAjax.phtml
deleted file mode 100644
index 790178cf70a..00000000000
--- a/themes/bootstrap3/templates/Recommend/ResultGoogleMapAjax.phtml
+++ /dev/null
@@ -1,205 +0,0 @@
-<?
-  $searchParams = $this->recommend->getSearchParams();
-
-  $this->headScript()->appendFile('https://maps.googleapis.com/maps/api/js?key=' . urlencode($this->recommend->getGoogleMapApiKey()) . '&sensor=false&language='.$this->layout()->userLang);
-  $this->headScript()->appendFile('vendor/markerclusterer.min.js');
-?>
-<script type="text/javascript">
-/**
- * Overriding clusterer default function for determining the label text and style
- * for a cluster icon.
- *
- * @param {Array.<google.maps.Marker>} markers The array of represented by the cluster.
- * @param {number} numStyles The number of marker styles available.
- * @return {ClusterIconInfo} The information resource for the cluster.
- * @constant
- * @ignore
- */
-MarkerClusterer.CALCULATOR = function (markers, numStyles) {
-  var index = 0;
-  var count = markers.length.toString();
-  var dispText = 0;
-  for (calcMarker in markers){
-    dispText = dispText + parseInt(markers[calcMarker].getTitle());
-  }
-  var dv = dispText;
-  while (dv !== 0) {
-    dv = parseInt(dv / 10, 10);
-    index++;
-  }
-
-  index = Math.min(index, numStyles);
-  return {
-    text: dispText.toString(),
-    index: index
-  };
-};
-
-/**
- * Overriding clusterer adding the icon to the DOM.
- */
-ClusterIcon.prototype.onAdd = function () {
-  var cClusterIcon = this;
-
-  this.div_ = document.createElement("div");
-  this.div_.className = "clusterDiv";
-  if (this.visible_) {
-    $(this).removeClass('hidden');
-  }
-
-  this.getPanes().overlayMouseTarget.appendChild(this.div_);
-
-  google.maps.event.addDomListener(this.div_, "click", function () {
-    var mc = cClusterIcon.cluster_.getMarkerClusterer();
-    google.maps.event.trigger(mc, "click", cClusterIcon.cluster_);
-    google.maps.event.trigger(mc, "clusterclick", cClusterIcon.cluster_); // deprecated name
-
-    // The default click handler follows. Disable it by setting
-    // the zoomOnClick property to false.
-    var mz = mc.getMaxZoom();
-    if (mc.getZoomOnClick()) {
-      // Zoom into the cluster.
-      mc.getMap().fitBounds(cClusterIcon.cluster_.getBounds());
-      // Don't zoom beyond the max zoom level
-      if (mz && (mc.getMap().getZoom() > mz)) {
-        mc.getMap().setZoom(mz + 1);
-      }
-    }
-  });
-
-  google.maps.event.addDomListener(this.div_, "mouseover", function () {
-    var mc = cClusterIcon.cluster_.getMarkerClusterer();
-    google.maps.event.trigger(mc, "mouseover", cClusterIcon.cluster_);
-  });
-
-  google.maps.event.addDomListener(this.div_, "mouseout", function () {
-    var mc = cClusterIcon.cluster_.getMarkerClusterer();
-    google.maps.event.trigger(mc, "mouseout", cClusterIcon.cluster_);
-  });
-};
-
-var markers;
-var mc;
-var markersData;
-var latlng;
-var myOptions;
-var map;
-var infowindow = new google.maps.InfoWindow({maxWidth: 480, minWidth: 480});
-
-function initialize() {
-  var url = VuFind.path+'/AJAX/json?method=getMapData&<?=$searchParams ?>';
-  //alert('go: ' + url);
-  $.getJSON(url, function(data){
-    //alert(data);
-    markersData = data['data'];
-    if (markersData.length <= 0){
-      return;
-    }
-    latlng = new google.maps.LatLng(0, 0);
-    myOptions = {
-      zoom: 1,
-      center: latlng,
-      mapTypeControl: true,
-      mapTypeControlOptions: {
-        style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
-      },
-      mapTypeId: google.maps.MapTypeId.ROADMAP
-    };
-    map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
-
-    var useGmm = document.getElementById('usegmm');
-    google.maps.event.addDomListener(useGmm, 'click', refreshMap);
-    map.addListener('zoom_changed', refreshMap);
-
-    var checkbx = document.getElementById("useCluster");
-    var wrap = document.getElementById("mapWrap");
-    wrap.style.display = "block";
-    checkbx.style.display = "block";
-
-    showMarkers();
-  });
-}
-
-function showMarkers(){
-  markers = [];
-
-  deleteOverlays();
-  if (mc) {
-    mc.clearMarkers();
-  }
-
-  for (var i = 0; i<markersData.length; i++){
-    var disTitle = markersData[i].title;
-    var iconSize = "0.5";
-    if (disTitle>99){
-      iconSize = "0.75";
-    }
-    var markerImg = "https://chart.googleapis.com/chart?chst=d_map_spin&chld="+iconSize+"|0|F44847|10|_|" +  disTitle;
-    var labelXoffset = 1 + disTitle.length * 4;
-    var latLng = new google.maps.LatLng(markersData[i].lat , markersData[i].lon)
-    var marker = new google.maps.Marker({//MarkerWithLabel
-      loc_facet: markersData[i].location_facet,
-      position: latLng,
-      map: map,
-      title: disTitle,
-      icon: markerImg
-    });
-    google.maps.event.addListener(marker, 'click', function() {
-      infowindow.close();
-      //infowindow.setContent(this.html);
-      //infowindow.open(map, this);
-      load_content(this);
-    });
-    markers.push(marker);
-  }
-  if (document.getElementById("usegmm").checked) {
-    mc = new MarkerClusterer(map, markers);
-  } else {
-    for (var i = 0; i < markers.length; i++) {
-      markers[i].setMap(map);
-    }
-  }
-}
-
-function load_content(marker){
-  var ajaxUrl = VuFind.path+'/AJAX/ResultGoogleMapInfo?limit=5&filter[]=long_lat%3A"' + marker.loc_facet+'"&<?=$searchParams ?>';
-  $.ajax(ajaxUrl, { dataType: 'html' }).done(function (html) {
-    infowindow.setContent(html);
-    infowindow.open(map, marker);
-  });
-}
-
-function deleteOverlays() {
-  if (markers) {
-    for (i in markers) {
-      markers[i].setMap(null);
-    }
-    markers.length = 0;
-  }
-}
-
-function refreshMap() {
-  deleteOverlays();
-  showMarkers();
-  // The following two lines are a workaround for a library bug that causes
-  // clusters to disappear after zoom and other events; these may be able to be
-  // removed along with the zoom_changed event hook above in the future if the
-  // library is fixed.
-  mapcenter = map.getCenter();
-  map.setCenter(new google.maps.LatLng((mapcenter.lat() + 0.0000001), mapcenter.lng()));
-}
-
-google.maps.event.addDomListener(window, 'load', initialize);
-</script>
-<div id="mapWrap" onload="initialize()" style="height:479px;display:none;margin-bottom:1em" class="clearfix">
-  <div id="map_canvas" style="width: 100%; height: 100%"></div>
-  <div class="mapClusterToggle" id="useCluster">
-    <div class="checkbox">
-      <label for="usegmm">
-        <input type="checkbox" id="usegmm" checked="true"></input>
-        <?=$this->transEsc('google_map_cluster_points') ?>
-      </label>
-    </div>
-  </div>
-</div>
-<br/>
diff --git a/themes/bootstrap3/templates/RecordTab/map.phtml b/themes/bootstrap3/templates/RecordTab/map.phtml
index ce4254a4a3e..34ce75b7aee 100644
--- a/themes/bootstrap3/templates/RecordTab/map.phtml
+++ b/themes/bootstrap3/templates/RecordTab/map.phtml
@@ -12,68 +12,4 @@
     <div id="map-canvas" style="width: 100%; height: 100%"><div id="popup"></div></div>
     <?=$this->inlineScript(\Zend\View\Helper\HeadScript::SCRIPT, $jsLoad, 'SET');?>
   </div>
-<? endif; ?>
-<? if (isset($mapType) && ($mapType == 'google')) : ?>
-  <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=<?=$this->tab->getGoogleMapApiKey()?>&amp;language=<?=$this->layout()->userLang?>"></script>
-  <script type="text/javascript">
-  var markers;
-  var markersData;
-  var latlng;
-  var myOptions;
-  var map;
-  var infowindow = new google.maps.InfoWindow({maxWidth: 480, minWidth: 480});
-  function initialize() {
-    markersData = <?=$this->tab->getGoogleMapMarker()?>;
-    latlng = new google.maps.LatLng(0, 0);
-    myOptions = {
-      zoom: 1,
-      center: latlng,
-      mapTypeControl: true,
-      mapTypeControlOptions: {
-          style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
-        },
-      mapTypeId: google.maps.MapTypeId.ROADMAP
-    };
-    map = new google.maps.Map(document.getElementById("map_canvas"),
-      myOptions);
-    showMarkers();
-  }
-  function showMarkers(){
-    deleteOverlays();
-    markers = [];
-    for (var i = 0; i<markersData.length; i++){
-      var disTitle = markersData[i][0].title ? markersData[i][0].title : '';
-      var iconTitle = disTitle;
-      if (disTitle.length>25){
-          iconTitle = disTitle.substring(0,25) + "...";
-      }
-      var markerImg = "https://chart.googleapis.com/chart?chst=d_bubble_text_small&chld=edge_bc|" + iconTitle +"|EEEAE3|";
-      var labelXoffset = 1 + disTitle.length * 4;
-      var latLng = new google.maps.LatLng(markersData[i][0].lat , markersData[i][0].lon)
-      var marker = new google.maps.Marker({
-        position: latLng,
-        map: map,
-        title: disTitle,
-        icon: markerImg
-      });
-      markers.push(marker);
-    }
-  }
-  function deleteOverlays() {
-      if (markers) {
-        for (i in markers) {
-          markers[i].setMap(null);
-        }
-        markers.length = 0;
-      }
-  }
-  function refreshMap() {
-    showMarkers();
-  }
-  google.maps.event.addDomListener(window, 'load', initialize);
-</script>
-
-<div id="wrap" onload="initialize()" style="width: 674px; height: 479px">
-  <div id="map_canvas" style="width: 100%; height: 100%"></div>
-</div>
-<? endif; ?>
+<? endif; ?>
\ No newline at end of file
-- 
GitLab