HowTo: Integrate OpenStreetMap into OpenImmo

In order to replace Google Maps with OpenStreetMap please follow these steps

  1. Create a file "OpenStreetMap.js" in your sitepackage, eg. at typo3conf/ext/sitepackage/Resources/Public/JavaScript/Openstreetmap.js You can find the sourcecode below.
  2. Overwrite the partial "GoogleMaps.html" with one in your sitepackage, eg.
    typo3conf/ext/sitepackage/Resources/Private/Extensions/Openimmo/Partials/Immobilie/Details/GoogleMaps.html

    You can find the sourcecode below. Please make sure to set the paths to your partials (see documentation chapter "Installation" --> "Configuration" for that.)

  3. Include the OpenStreetMap javascript files and deactivate the Google Maps javascript files via typoscript setup:
    # Include OpenStreetMap and remove Google Maps libraries
    page {
       includeJSFooterlibs {
           openLayers = https://openlayers.org/api/OpenLayers.js
           openStreetMap = https://openstreetmap.org/openlayers/OpenStreetMap.js
           openStreetMapLocal = typo3conf/ext/theme_paperclip_child/Resources/Public/JavaScript/Openstreetmap.js
           googleMaps =
           googleMapsHtmlMarker =
           googleMapsClustering =
       }
    }

OpenStreetMap.js

var openStreetMap = {
    map: null,
    layer_mapnik: null,
    layer_tah: null,
    layer_markers: null,

    jumpTo: function (lon, lat, zoom) {
        var x = this.Lon2Merc(lon);
        var y = this.Lat2Merc(lat);
        map.setCenter(new OpenLayers.LonLat(x, y), zoom);
        return false;
    },

    Lon2Merc: function (lon) {
        return 20037508.34 * lon / 180;
    },

    Lat2Merc: function (lat) {
        var PI = 3.14159265358979323846;
        lat = Math.log(Math.tan( (90 + lat) * PI / 360)) / (PI / 180);
        return 20037508.34 * lat / 180;
    },

    addMarker: function (layer, lon, lat, popupContentHTML) {
        var ll = new OpenLayers.LonLat(this.Lon2Merc(lon), this.Lat2Merc(lat));
        var feature = new OpenLayers.Feature(layer, ll);
        feature.closeBox = true;
        feature.popupClass = OpenLayers.Class(OpenLayers.Popup.FramedCloud, {minSize: new OpenLayers.Size(300, 180) } );
        feature.data.popupContentHTML = popupContentHTML;
        feature.data.overflow = "hidden";

        var marker = new OpenLayers.Marker(ll);
        marker.feature = feature;

        var markerClick = function(evt) {
            if (this.popup == null) {
                this.popup = this.createPopup(this.closeBox);
                map.addPopup(this.popup);
                this.popup.show();
            } else {
                this.popup.toggle();
            }
            OpenLayers.Event.stop(evt);
        };
        marker.events.register("mousedown", feature, markerClick);

        layer.addMarker(marker);
        //map.addPopup(feature.createPopup(feature.closeBox));
    },

    getCycleTileURL: function (bounds) {
        var res = this.map.getResolution();
        var x = Math.round((bounds.left - this.maxExtent.left) / (res * this.tileSize.w));
        var y = Math.round((this.maxExtent.top - bounds.top) / (res * this.tileSize.h));
        var z = this.map.getZoom();
        var limit = Math.pow(2, z);

        if (y < 0 || y >= limit)
        {
            return null;
        } else {
            x = ((x % limit) + limit) % limit;
            return this.url + z + "/" + x + "/" + y + "." + this.type;
        }
    },

    drawmap: function(dataElementId, mapElementId, zoom) {
        OpenLayers.Lang.setCode('de');

        // Set position and zoom of the map, take the data from the dataElement
        // Data attributes need to be set: lat, lon, title
        const dataElement = document.querySelector('#' + dataElementId);
        let lat = parseFloat(dataElement.dataset.latitude);
        let lon = parseFloat(dataElement.dataset.longitude);
        let popUpContentHtml = dataElement.dataset.title;

        map = new OpenLayers.Map(mapElementId, {
            projection: new OpenLayers.Projection("EPSG:900913"),
            displayProjection: new OpenLayers.Projection("EPSG:4326"),
            controls: [
                new OpenLayers.Control.Navigation(),
                new OpenLayers.Control.PanZoomBar()],
            maxExtent:
                new OpenLayers.Bounds(-20037508.34, -20037508.34,
                    20037508.34, 20037508.34),
            numZoomLevels: 18,
            maxResolution: 156543,
            units: 'meters'
        });

        layer_mapnik = new OpenLayers.Layer.OSM.Mapnik("Mapnik");
        layer_markers = new OpenLayers.Layer.Markers("Address", {
            projection: new OpenLayers.Projection("EPSG:4326"),
            visibility: true,
            displayInLayerSwitcher: false
        });

        map.addLayers([layer_mapnik, layer_markers]);
        this.jumpTo(lon, lat, zoom);
        this.addMarker(layer_markers, lon, lat, popUpContentHtml);
    }
}

jQuery(document).ready(function() {
    // Draw the OpenStreetMap if a map element is on this page
    if(jQuery('#openimmo-google-map-points-of-interest').length > 0) {
        openStreetMap.drawmap(
            'openimmo-google-map-points-of-interest',
            'openimmo-google-map-points-of-interest',
            15
        );
    }
    if(jQuery('#address-detail-map').length > 0) {
        openStreetMap.drawmap(
            'address-detail-map',
            'address-detail-map',
            12
        );
    }
});

GoogleMaps.html

<div xmlns="http://www.w3.org/1999/xhtml" lang="en"
     xmlns:f="http://typo3.org/ns/fluid/ViewHelpers"
     xmlns:oi="http://typo3.org/ns/CodingMs/Openimmo/ViewHelpers">
    <f:section name="Bootstrap4">

        <f:if condition="{oi:extension.loaded(extensionName: 'OpenimmoPro', then: '1', else: '0')}">
            <f:if condition="{settings.pro}">
                <f:comment>Show map, but only if coordinates are available</f:comment>
                <oi:variable.set name="map"><oi:googleMaps.detail immobilie="{immobilie}" settings="{settings}" /></oi:variable.set>
                <f:if condition="{map}">
                    <div class="row">
                        <!-- Define also an id for anchor accessibility -->
                        <div class="openimmo-details-map col-md-12" id="openimmo-detail-map">
                            <div class="card">
                                <f:if condition="1">
                                    <div class="card-body">
                                        <div class="card-title-wrapper">
                                            <h3 class="card-title"><f:translate key="tx_openimmo_label.immobilie_points_of_interest" /></h3>
                                        </div>
                                    </div>
                                </f:if>
                                <div class="openimmo-google-map-points-of-interest">
                                    <f:format.raw>{map}</f:format.raw>
                                </div>
                                <div id="osm">© <a href="http://www.openstreetmap.org">OpenStreetMap</a>
                                    und <a href="http://www.openstreetmap.org/copyright">Mitwirkende</a>,
                                    <a href="http://creativecommons.org/licenses/by-sa/2.0/deed.de">CC-BY-SA</a>
                                </div>
                            </div>
                        </div>
                    </div>
                </f:if>
            </f:if>
        </f:if>

    </f:section>
</div>