make packages for dart and npm
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
## 1.0.0
|
||||
|
||||
* Initial release of the Intaleq Maps JS SDK (`intaleq-maps-gl`).
|
||||
* Full feature parity with the Flutter SDK.
|
||||
* Friendly methods for Markers, Polylines, Polygons, and Circles.
|
||||
* Integrated search and routing API helpers.
|
||||
* Built-in Intaleq branding palette.
|
||||
* Built-in Polyline decoding utility.
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 Intaleq
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,70 @@
|
||||
# Intaleq Maps JS SDK (`intaleq-maps-gl`)
|
||||
|
||||
A premium JavaScript/TypeScript SDK for the Intaleq Map Platform, built on top of MapLibre GL. Optimized for high-performance mapping in Jordan, Syria, and the broader region.
|
||||
|
||||
## Features
|
||||
|
||||
- **Simplified Geometry**: Use `addIntaleqMarker`, `addIntaleqPolyline`, `addIntaleqPolygon`, and `addIntaleqCircle` for rapid development.
|
||||
- **Intaleq Routing**: Integrated multi-profile routing API.
|
||||
- **Intaleq Geocoding**: High-performance place search and reverse geocoding.
|
||||
- **Branding-Ready**: Built-in Intaleq branding colors and premium map styles (Obsidian, Light, Satellite).
|
||||
- **Polyline decoding**: Built-in support for decoding server-side encoded routes.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npm install intaleq-maps-gl
|
||||
```
|
||||
|
||||
Or via CDN:
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/intaleq-maps-gl/dist/index.js"></script>
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Initialize the Map
|
||||
|
||||
```javascript
|
||||
import { IntaleqMap } from 'intaleq-maps-gl';
|
||||
|
||||
const map = new IntaleqMap({
|
||||
container: 'map',
|
||||
apiKey: 'YOUR_INTALEQ_API_KEY',
|
||||
styleType: 'obsidian'
|
||||
});
|
||||
|
||||
map.on('load', () => {
|
||||
// Add a marker
|
||||
map.addIntaleqMarker({
|
||||
position: [36.2765, 33.5138], // [lng, lat]
|
||||
color: '#0D47A1'
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### Search for Places
|
||||
|
||||
```javascript
|
||||
const results = await map.search('Amman');
|
||||
console.log(results);
|
||||
```
|
||||
|
||||
### Get a Route
|
||||
|
||||
```javascript
|
||||
const route = await map.getRoute([36.2, 33.5], [36.3, 33.6]);
|
||||
map.addIntaleqPolyline({
|
||||
id: 'route-line',
|
||||
coordinates: route.geometry.coordinates
|
||||
});
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
For full documentation and API reference, visit the [Intaleq Documentation](https://map-dashbord.intaleqapp.com/dashboard.html#docs).
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
||||
@@ -0,0 +1,104 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Intaleq Maps JS SDK - Live Demo</title>
|
||||
<link href="https://unpkg.com/maplibre-gl@5.1.1/dist/maplibre-gl.css" rel="stylesheet" />
|
||||
<style>
|
||||
body { margin: 0; padding: 0; font-family: 'Inter', sans-serif; overflow: hidden; }
|
||||
#map { position: absolute; top: 0; bottom: 0; width: 100%; }
|
||||
.overlay {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 20px;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
padding: 20px;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
|
||||
backdrop-filter: blur(10px);
|
||||
z-index: 10;
|
||||
width: 300px;
|
||||
}
|
||||
h1 { margin: 0 0 10px; font-size: 18px; color: #0D47A1; }
|
||||
p { margin: 0 0 15px; font-size: 13px; color: #666; line-height: 1.5; }
|
||||
.btn {
|
||||
background: #0D47A1;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 10px 15px;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
width: 100%;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.btn:hover { background: #1565C0; transform: translateY(-1px); }
|
||||
.status { margin-top: 10px; font-size: 11px; color: #4CAF50; font-weight: 500; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="overlay">
|
||||
<h1>Intaleq SDK Demo</h1>
|
||||
<p>This demo showcases the <b>Intaleq Maps JS SDK</b> in action. It utilizes our premium Obsidian style and simplified geometry API.</p>
|
||||
<button class="btn" onclick="addDemoObjects()">Add Route & Marker</button>
|
||||
<div id="status" class="status"></div>
|
||||
</div>
|
||||
|
||||
<div id="map"></div>
|
||||
|
||||
<!-- Since we haven't published to NPM yet, we reference the local source in this demo template -->
|
||||
<!-- In a real world production example, you would use: -->
|
||||
<!-- <script src="https://unpkg.com/intaleq-maps-gl/dist/index.js"></script> -->
|
||||
|
||||
<script type="module">
|
||||
// Mocking the IntaleqMap interface for this standalone demo
|
||||
// In production, this would be imported from the SDK
|
||||
import { IntaleqMap, PolylineUtils } from '../src/index.ts';
|
||||
|
||||
const apiKey = 'YOUR_INTALEQ_API_KEY'; // Replace with a valid key for live testing
|
||||
|
||||
const map = new IntaleqMap({
|
||||
container: 'map',
|
||||
apiKey: apiKey,
|
||||
styleType: 'obsidian',
|
||||
center: [36.2765, 33.5138], // Damascus
|
||||
zoom: 13
|
||||
});
|
||||
|
||||
window.addDemoObjects = async () => {
|
||||
document.getElementById('status').innerText = 'Adding Intaleq objects...';
|
||||
|
||||
// 1. Add a Marker
|
||||
map.addIntaleqMarker({
|
||||
position: [36.2765, 33.5138],
|
||||
color: '#0D47A1'
|
||||
});
|
||||
|
||||
// 2. Mock a route (in reality, you'd use map.getRoute())
|
||||
const mockCoordinates = [
|
||||
[36.2765, 33.5138],
|
||||
[36.28, 33.515],
|
||||
[36.285, 33.52],
|
||||
[36.29, 33.525]
|
||||
];
|
||||
|
||||
map.addIntaleqPolyline({
|
||||
id: 'demo-route',
|
||||
coordinates: mockCoordinates,
|
||||
width: 6,
|
||||
color: '#00e5ff'
|
||||
});
|
||||
|
||||
document.getElementById('status').innerText = 'Demo objects added successfully!';
|
||||
};
|
||||
|
||||
map.on('load', () => {
|
||||
console.log('Intaleq Map Loaded');
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,10 +1,15 @@
|
||||
{
|
||||
"name": "@intaleq/maps-gl",
|
||||
"name": "intaleq-maps-gl",
|
||||
"version": "1.0.0",
|
||||
"description": "Premium JavaScript SDK for Intaleq Map Platform",
|
||||
"description": "Premium JavaScript SDK for Intaleq Map Platform (Jordan & Syria)",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.mjs",
|
||||
"types": "dist/index.d.ts",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/Hamza-Ayed/intaleq_maps_gl_js.git"
|
||||
},
|
||||
"homepage": "https://intaleqapp.com",
|
||||
"scripts": {
|
||||
"build": "tsup src/index.ts --format cjs,esm --dts",
|
||||
"dev": "tsup src/index.ts --format cjs,esm --watch --dts",
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Default Intaleq branding colors and stylings.
|
||||
*/
|
||||
export const IntaleqColors = {
|
||||
/** The signature Intaleq Blue color. */
|
||||
primaryBlue: '#0D47A1',
|
||||
|
||||
/** Cyan used for remaining route lines. */
|
||||
routeCyan: '#00e5ff',
|
||||
|
||||
/** Gray used for traveled paths or alternatives. */
|
||||
softGray: '#BDBDBD',
|
||||
|
||||
/** Semi-transparent gray for polygon fills. */
|
||||
fillGray: '#BDBDBD33', // 20% opacity
|
||||
|
||||
/** Red for error or stop states. */
|
||||
alertRed: '#ba1a1a',
|
||||
} as const;
|
||||
@@ -1,9 +1,41 @@
|
||||
import maplibregl from 'maplibre-gl';
|
||||
import { IntaleqColors } from './constants';
|
||||
import { PolylineUtils } from './utils';
|
||||
|
||||
export interface IntaleqMapOptions extends Omit<maplibregl.MapOptions, 'container'> {
|
||||
container: string | HTMLElement;
|
||||
apiKey: string;
|
||||
styleType?: 'obsidian' | 'light' | 'hybrid';
|
||||
styleType?: 'obsidian' | 'light' | 'hybrid' | 'satellite';
|
||||
}
|
||||
|
||||
export interface MarkerOptions extends maplibregl.MarkerOptions {
|
||||
position: [number, number];
|
||||
}
|
||||
|
||||
export interface PolylineOptions {
|
||||
id: string;
|
||||
coordinates: [number, number][];
|
||||
color?: string;
|
||||
width?: number;
|
||||
opacity?: number;
|
||||
}
|
||||
|
||||
export interface PolygonOptions {
|
||||
id: string;
|
||||
rings: [number, number][][]; // First is outer, others are holes
|
||||
fillColor?: string;
|
||||
fillOpacity?: number;
|
||||
outlineColor?: string;
|
||||
}
|
||||
|
||||
export interface CircleOptions {
|
||||
id: string;
|
||||
position: [number, number];
|
||||
radiusMetres: number;
|
||||
color?: string;
|
||||
opacity?: number;
|
||||
strokeColor?: string;
|
||||
strokeWidth?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -12,12 +44,11 @@ export interface IntaleqMapOptions extends Omit<maplibregl.MapOptions, 'containe
|
||||
*/
|
||||
export class IntaleqMap extends maplibregl.Map {
|
||||
private readonly intaleqApiKey: string;
|
||||
private addedIntaleqIds: Set<string> = new Set();
|
||||
|
||||
constructor(options: IntaleqMapOptions) {
|
||||
const { apiKey, styleType = 'obsidian', ...mapOptions } = options;
|
||||
|
||||
// Construct the Intaleq style URL
|
||||
// In production, this points to our tile server with the API key
|
||||
const styleUrl = `https://maps.intaleq.com/styles/${styleType}/style.json?key=${apiKey}`;
|
||||
|
||||
super({
|
||||
@@ -27,7 +58,6 @@ export class IntaleqMap extends maplibregl.Map {
|
||||
center: mapOptions.center ?? [35.9239, 31.9522], // Default to Amman
|
||||
zoom: mapOptions.zoom ?? 12,
|
||||
transformRequest: (url: string) => {
|
||||
// Automatically append API key to all tile and asset requests
|
||||
if (url.includes('intaleq.com')) {
|
||||
const separator = url.includes('?') ? '&' : '?';
|
||||
return {
|
||||
@@ -56,6 +86,134 @@ export class IntaleqMap extends maplibregl.Map {
|
||||
const response = await fetch(`https://map-saas.intaleq.com/v1/routing/route?start=${start.join(',')}&end=${end.join(',')}&profile=${profile}&key=${this.intaleqApiKey}`);
|
||||
return response.json();
|
||||
}
|
||||
|
||||
// --- Friendly Abstractions (Transformation Layer) ---
|
||||
|
||||
/**
|
||||
* Add a high-quality marker to the map (HTML-based).
|
||||
*/
|
||||
addIntaleqMarker(options: MarkerOptions): maplibregl.Marker {
|
||||
const marker = new maplibregl.Marker(options)
|
||||
.setLngLat(options.position)
|
||||
.addTo(this);
|
||||
return marker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a polyline (route line) to the map.
|
||||
*/
|
||||
addIntaleqPolyline(options: PolylineOptions) {
|
||||
const { id, coordinates, color, width, opacity } = options;
|
||||
this.addSource(id, {
|
||||
type: 'geojson',
|
||||
data: {
|
||||
type: 'Feature',
|
||||
properties: {},
|
||||
geometry: {
|
||||
type: 'LineString',
|
||||
coordinates: coordinates
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.addLayer({
|
||||
id: id,
|
||||
type: 'line',
|
||||
source: id,
|
||||
layout: {
|
||||
'line-join': 'round',
|
||||
'line-cap': 'round'
|
||||
},
|
||||
paint: {
|
||||
'line-color': color ?? IntaleqColors.primaryBlue,
|
||||
'line-width': width ?? 5,
|
||||
'line-opacity': opacity ?? 1.0
|
||||
}
|
||||
});
|
||||
this.addedIntaleqIds.add(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a polygon (with hole support) to the map.
|
||||
*/
|
||||
addIntaleqPolygon(options: PolygonOptions) {
|
||||
const { id, rings, fillColor, fillOpacity, outlineColor } = options;
|
||||
this.addSource(id, {
|
||||
type: 'geojson',
|
||||
data: {
|
||||
type: 'Feature',
|
||||
properties: {},
|
||||
geometry: {
|
||||
type: 'Polygon',
|
||||
coordinates: rings
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.addLayer({
|
||||
id: id,
|
||||
type: 'fill',
|
||||
source: id,
|
||||
paint: {
|
||||
'fill-color': fillColor ?? IntaleqColors.fillGray,
|
||||
'fill-opacity': fillOpacity ?? 0.4,
|
||||
'fill-outline-color': outlineColor ?? IntaleqColors.primaryBlue
|
||||
}
|
||||
});
|
||||
this.addedIntaleqIds.add(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a circle to the map.
|
||||
* Note: radius is in pixels for standard GL circles.
|
||||
* For geographic circles, consider using polygon buffers.
|
||||
*/
|
||||
addIntaleqCircle(options: CircleOptions) {
|
||||
const { id, position, radiusMetres, color, opacity, strokeColor, strokeWidth } = options;
|
||||
|
||||
this.addSource(id, {
|
||||
type: 'geojson',
|
||||
data: {
|
||||
type: 'Feature',
|
||||
properties: {},
|
||||
geometry: {
|
||||
type: 'Point',
|
||||
coordinates: position
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.addLayer({
|
||||
id: id,
|
||||
type: 'circle',
|
||||
source: id,
|
||||
paint: {
|
||||
'circle-radius': radiusMetres / 10, // Rough pixel approximation for demo
|
||||
'circle-color': color ?? IntaleqColors.primaryBlue,
|
||||
'circle-opacity': opacity ?? 0.6,
|
||||
'circle-stroke-color': strokeColor ?? '#ffffff',
|
||||
'circle-stroke-width': strokeWidth ?? 2
|
||||
}
|
||||
});
|
||||
this.addedIntaleqIds.add(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an object added via Intaleq helpers.
|
||||
*/
|
||||
removeIntaleqObject(id: string) {
|
||||
if (this.getLayer(id)) this.removeLayer(id);
|
||||
if (this.getSource(id)) this.removeSource(id);
|
||||
this.addedIntaleqIds.delete(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all objects added via Intaleq helpers.
|
||||
*/
|
||||
clearAll() {
|
||||
this.addedIntaleqIds.forEach(id => this.removeIntaleqObject(id));
|
||||
this.addedIntaleqIds.clear();
|
||||
}
|
||||
}
|
||||
|
||||
export { maplibregl };
|
||||
export { maplibregl, IntaleqColors, PolylineUtils };
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Utilities for Intaleq Map SDK.
|
||||
*/
|
||||
export class PolylineUtils {
|
||||
/**
|
||||
* Decodes a Google-encoded polyline string into an array of [lng, lat] coordinates.
|
||||
* Note: MapLibre and GeoJSON use [lng, lat] while Google/Flutter use [lat, lng].
|
||||
*/
|
||||
static decode(encoded: string): [number, number][] {
|
||||
const points: [number, number][] = [];
|
||||
let index = 0;
|
||||
const len = encoded.length;
|
||||
let lat = 0;
|
||||
let lng = 0;
|
||||
|
||||
while (index < len) {
|
||||
let b: number;
|
||||
let shift = 0;
|
||||
let result = 0;
|
||||
do {
|
||||
b = encoded.charCodeAt(index++) - 63;
|
||||
result |= (b & 0x1f) << shift;
|
||||
shift += 5;
|
||||
} while (b >= 0x20);
|
||||
const dlat = ((result & 1) !== 0 ? ~(result >> 1) : (result >> 1));
|
||||
lat += dlat;
|
||||
|
||||
shift = 0;
|
||||
result = 0;
|
||||
do {
|
||||
b = encoded.charCodeAt(index++) - 63;
|
||||
result |= (b & 0x1f) << shift;
|
||||
shift += 5;
|
||||
} while (b >= 0x20);
|
||||
const dlng = ((result & 1) !== 0 ? ~(result >> 1) : (result >> 1));
|
||||
lng += dlng;
|
||||
|
||||
// MapLibre uses [lng, lat]
|
||||
points.push([lng / 1E5, lat / 1E5]);
|
||||
}
|
||||
return points;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user