Add Events to a Mapbox map via PHP
7 min read

Add Events to a Mapbox map via PHP

Add Events to a Mapbox map via PHP

Adding a map to your application is very easy to do these days. You might use the more popular google maps, but Mapbox makes this process really simple. In order to create a map, you will use Javascript, but to save and provide data for the map we will use php.

Video Guide:

Source Code:

GitHub - mbouldo/mapbox-events-php: Add events to a map via mapbox & retrieve data async via JS and PHP
Add events to a map via mapbox & retrieve data async via JS and PHP - GitHub - mbouldo/mapbox-events-php: Add events to a map via mapbox & retrieve data async via JS and PHP
Maps | Mapbox
Unparalleled speed and customization to visualize your world.
Documentation
Examples, tutorials, and API references to help you start building with Mapbox.
Installation | Mapbox GL JS
Get started with Mapbox GL JS.

Written Guide:

Basic Pages, and styles

Basic HTML

<div class="flex font-sans">
    <!-- SIDEBAR -->
    <div class="w-1/5 bg-gray-900 h-screen">
        <!-- LOGO -->
        <div class="flex justify-center pt-8 pb-8 border-b border-b-white">
            <img src="../dist/mapbox-logo-white.svg" class="h-14" />
        </div>

        <!-- HEADING -->
        <h3 class="text-white font-bold  text-center text-3xl mt-8 flex items-center w-full justify-center">
            <svg xmlns="http://www.w3.org/2000/svg" class="h-10 w-10 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor"
                stroke-width="2">
                <path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
            </svg>
            Add an Event
        </h3>

        <!-- ADD EVENT FORM -->
        <div class="mb-6 w-5/6 mx-auto mt-12">
            <label for="eventName" class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300">Event Name</label>
            <input type="text" id="eventName" class="input-field" placeholder="DC Event" required>
        </div>

        <div class="mb-6 w-5/6 mx-auto mt-6">
            <label for="eventDescription" class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300">Event
                Description</label>
            <input type="text" id="eventDescription" class="input-field" placeholder="There will be very cool refreshments"
                required>
        </div>
        
        <div class="mb-6 w-5/6 mx-auto mt-6">
            <label for="geocoder" class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300">Event Address</label>
            <div id="geocoder"></div>
        </div>
        
        <div class="w-5/6 mx-auto flex justify-end">
            <button type="button" class="submit-button" onclick="addEvent()">Add Event</button>
        </div>
    </div>
    <!-- MAP -->
    <div class="h-screen w-full" id="map"></div>
</div>

Styles

mapbox-events-php/output.css at main · mbouldo/mapbox-events-php
Add events to a map via mapbox & retrieve data async via JS and PHP - mapbox-events-php/output.css at main · mbouldo/mapbox-events-php

Header Dependencies

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&family=Poppins:wght@400;500;600;700;900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v5.0.0/mapbox-gl-geocoder.css" type="text/css">
<link href="../dist/output.css" rel="stylesheet">

Mapbox, JQuery Dependencies

<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script src='https://api.mapbox.com/mapbox-gl-js/v2.9.1/mapbox-gl.js'></script>
<link href='https://api.mapbox.com/mapbox-gl-js/v2.9.1/mapbox-gl.css' rel='stylesheet' />
<script src="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v5.0.0/mapbox-gl-geocoder.min.js"></script>

Initialize Your Map (In a script tag)

mapboxgl.accessToken = 'YOUR_MAPBOX_TOKEN_HERE';

var map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/mapbox/streets-v11',
    center: [-77.04, 38.907],
    zoom: 11.15
});

Get Events Data & Add to Map

Load an icons layer onto your map

map.on('load', function () {
    //place object we will add our events to
    map.addSource('places',{
        'type': 'geojson',
        'data': {
            'type': 'FeatureCollection',
            'features': []
        }
    });
    //add place object to map
    map.addLayer({
        'id': 'places',
        'type': 'symbol',
        'source': 'places',
        'layout': {
            'icon-image': '{icon}',
            'icon-allow-overlap': true
        }
    });

    //Handle popups
    map.on('click', 'places', (e) => {
        const coordinates = e.features[0].geometry.coordinates.slice();
        const description = e.features[0].properties.description;
        while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
            coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
    }
    new mapboxgl.Popup()
        .setLngLat(coordinates)
        .setHTML(description)
        .addTo(map);
    });

    //Handle pointer styles
    map.on('mouseenter', 'places', () => {
        map.getCanvas().style.cursor = 'pointer';
    });
    map.on('mouseleave', 'places', () => {
        map.getCanvas().style.cursor = '';
    });

    //get our data from php function
    //getAllEvents();
});

Async get events data from PHP

function getAllEvents(){
    $.ajax({
        url: "../api/getAllEvents.php",
        contentType: "application/json",
        dataType: "json",
        success: function (eventData) {
            console.log(eventData)
            map.getSource('places').setData({
                    'type': 'FeatureCollection',
                    'features': eventData
            });
        },
        error: function (e) {
            console.log(e);
        }
    });
}

Create a new database

Add an events table

Create your id, event, lat, lng columns, name, and description

Your table should look like this:

Connect your PHP file that handles events to your DB

<?php

$db = "mapboxevents";
$host = "localhost";
$user = 'USERNAME';
$pass = 'PASSWORD';

//PDO Connection
try {
    $pdo = new PDO("mysql:host=$host;dbname=$db", $user, $pass);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    //echo "Connected successfully";
}
catch(PDOException $e){
    //echo "Connection failed: " . $e->getMessage();
}

function p($arr){
    echo "<pre>";
        print_r($arr);
    echo "</pre>";
}

Get event data from your events table

$sql = "SELECT * FROM events";

try {
    $stmt = $pdo->prepare($sql);
    $stmt->execute();
    $data = $stmt->fetchAll(PDO::FETCH_ASSOC);

} catch (Exception $e) {
    die($e);
}

Morph your $data from mySQL Into json Mapbox can use

foreach ($data as $key => $eventData) {
    $returnData[] = [
        'type' => 'Feature'.$eventData['id'],
        'properties' => [
            'description' => '<strong>'.$eventData['name'].'</strong><p>'.$eventData['description'].'</p>',
            'icon' => 'rocket-15'
        ],
        'geometry' => [
            'type' => 'Point',
            'coordinates' => [$eventData['lat'], $eventData['lng']]
        ]
    ];
}

Set your headers to support json, and echo out your json

//top of file
header('Content-Type: application/json; charset=utf-8');
include('db.php');

//bottom of file
echo json_encode($returnData);

Test your first event, by adding it into your mySQL

INSERT INTO `events` (`id`, `name`, `description`, `lat`, `lng`) VALUES (NULL, 'Manual mySQL', 'Test mySQL event', '-77.0877945', '38.937867');

Add events to your database:

Your php file will contain a simple PDO sql statement that will insert all of the posted variables, including name, description, lat, and lng

PHP Process File that will add to DB

<?php
// api/createEvent.php
include('db.php');

if(isset($_POST['name'])){
    $sql = "INSERT into events (name,description,lat,lng) VALUES (:name,:description,:lat,:lng)";
    try {
        $stmt = $pdo->prepare($sql);
        $stmt->execute([
            'name'=>$_POST['name'],
            'description'=>$_POST['description'],
            'lat'=>$_POST['lat'],
            'lng'=>$_POST['lng'],
        ]);

        echo json_encode('success');
    
    } catch (Exception $e) {
        die($e);
    }
}

Async JavaScript file to call your API file

function addEvent(){
    $.ajax({
        url: "../api/createEvent.php",
        type:'POST',
        data:postObj,
        dataType: "json",
        success: function (resp) {
            
        },
        error: function (e) {
            console.log(e);
        }
    });
}

Initialize Your Geocoder to get lat, lng data

const geocoder = new MapboxGeocoder({
    accessToken: mapboxgl.accessToken,
});

geocoder.addTo('#geocoder');

var geocoderResult = {};
geocoder.on('result', (e) => {
    geocoderResult = e.result, null, 2;
});

// Clear results container when search is cleared.
geocoder.on('clear', () => {
    geocoderResult = {};
});

Validate if geocoder is set & set postData

    if(geocoderResult=={}){
        return false;
    }
    var postObj = {
        name:$("#eventName").val(),
        description:$("#eventDescription").val(),
        lat:geocoderResult.center[0],
        lng:geocoderResult.center[1],
    }

Handle success when event is created

//reset form & get new data
$("#eventName").val('');
$("#eventDescription").val('');
geocoder.clear();
getAllEvents();