Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Support for OpenStreetMap #48

Open
1 of 2 tasks
aaronbrethorst opened this issue Sep 8, 2024 · 0 comments
Open
1 of 2 tasks

Add Support for OpenStreetMap #48

aaronbrethorst opened this issue Sep 8, 2024 · 0 comments
Assignees

Comments

@aaronbrethorst
Copy link
Member

aaronbrethorst commented Sep 8, 2024

User story

as a transit agency operator,
I want to use OpenStreetMap instead of Google Maps,
to cut costs and increase flexibility

Acceptance Criteria

  • Add support for switching between Google Maps and OSM at the .env level
  • Use a plugin architecture so we can add other maps in the future.

Explanation

The plugin architecture would center around creating a common interface that all map provider plugins must implement. This interface would define methods for essential map operations like initializing the map, setting the view, adding markers, and handling user interactions. You'd create a base class that outlines these required methods.

To implement a specific map provider, you'd create a new class that extends this base class or implements the interface. For example, you might have an OpenStreetMapProvider class and a GoogleMapProvider class. Each of these would implement the required methods using the specific API calls and conventions of their respective mapping libraries. The rest of your application would then interact with maps through this common interface, without needing to know the details of the specific provider being used.

To switch between providers, you'd simply need to instantiate the appropriate provider class and pass it to the components that need map functionality. You could even make this configurable, allowing users to choose their preferred map provider through a settings menu. This architecture promotes modularity and makes it easier to add support for new map providers in the future without having to modify the core application logic.

Example code

// Define the base class for map providers
class MapProvider {
  initMap(elementId) {
    throw new Error('initMap must be implemented');
  }
  
  setView(lat, lon, zoom) {
    throw new Error('setView must be implemented');
  }
  
  addMarker(lat, lon, popupText) {
    throw new Error('addMarker must be implemented');
  }
  // Add other common methods as needed
}

// OpenStreetMap implementation
class OpenStreetMapProvider extends MapProvider {
  constructor() {
    super();
    this.map = null;
  }

  initMap(elementId) {
    this.map = L.map(elementId); // Using Leaflet.js for OSM
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(this.map);
  }

  setView(lat, lon, zoom) {
    this.map.setView([lat, lon], zoom);
  }

  addMarker(lat, lon, popupText) {
    L.marker([lat, lon]).addTo(this.map).bindPopup(popupText);
  }
}

// Google Maps implementation
class GoogleMapProvider extends MapProvider {
  constructor() {
    super();
    this.map = null;
  }

  initMap(elementId) {
    this.map = new google.maps.Map(document.getElementById(elementId), {
      center: { lat: 0, lng: 0 },
      zoom: 8
    });
  }

  setView(lat, lon, zoom) {
    this.map.setCenter({ lat, lng: lon });
    this.map.setZoom(zoom);
  }

  addMarker(lat, lon, popupText) {
    new google.maps.Marker({
      position: { lat, lng: lon },
      map: this.map,
      title: popupText
    });
  }
}

// Usage in a Svelte component
export default {
  props: ['mapProvider'],
  
  onMount() {
    const { mapProvider } = this.props;
    mapProvider.initMap('map-container');
    mapProvider.setView(51.505, -0.09, 13);
    mapProvider.addMarker(51.5, -0.09, 'Hello, London!');
  }
};

// In your HTML
// <div id="map-container" style="height: 400px;"></div>

// In your main app or settings
const useOpenStreetMap = true;
const mapProvider = useOpenStreetMap ? new OpenStreetMapProvider() : new GoogleMapProvider();

// Pass mapProvider to your map component
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants