A standalone web application that systematically scans the Sfax, Tunisia region to check fiber (GPON) coverage using the Tunisie Telecom API. The app displays results on an interactive map with comprehensive statistics and export capabilities.
- 🗺️ Interactive Map: Built with Leaflet.js and OpenStreetMap tiles
- 🔍 Fine Grid Scanning: Configurable scan area and grid density (~200m between points)
- 📊 Real-time Visualization: Circle markers with color coding (green=available, red=not available, yellow=error)
- 📈 Progress Tracking: Live progress bar and statistics during scanning
- 🔄 Retry Not Available Points: Re-scan points that were marked as "Not Available" to check if status has changed
- 🔥 Heatmap Layer: Optional heatmap visualization of coverage data
- 📥 Export Results: Download scan data as JSON or CSV
- 💾 Results Persistence: Automatic saving to localStorage with restore on page load
- 🎯 Custom Bounds: Draw rectangles on the map to define custom scan areas
- ⚙️ Configurable Settings: Adjust scan bounds, step size, and API request delay
- 📱 Responsive Design: Works on desktop and mobile devices
To run the app locally without CORS errors, use the built-in dev server:
npm install
npm run devThen open http://localhost:3000 in your browser.
The dev server:
- Serves
index.html,script.js,style.css, and other static files - Proxies API requests from
/api/rsm/*tohttps://gis.tunisietelecom.tn/rsm/*
Warning
Opening index.html directly as a file (file://) or via a simple file server that does not proxy API calls will result in CORS errors because the browser blocks cross-origin requests to gis.tunisietelecom.tn.
-
Open the Application
- Run
npm run devand open http://localhost:3000 (see Local Development above) - Or deploy to GitHub Pages / a custom domain — API calls go directly without a proxy
- Run
-
Configure Scan Area
- Use the default Sfax region bounds (34.70-34.78 lat, 10.72-10.80 lng)
- Or adjust the latitude/longitude min/max values in the control panel
- Or enable "Draw Custom Bounds" and draw a rectangle on the map
-
Adjust Settings
- Step Size: Distance between scan points in degrees (default: 0.002° ≈ 200m)
- Delay: Time between API requests in milliseconds (default: 500ms)
- The app automatically calculates the total number of points
-
Start Scanning
- Click "Start Scan" to begin
- Use "Pause" to temporarily stop (resume later)
- Use "Stop" to end the scan completely
- Progress is shown in real-time with a progress bar
-
View Results
- 🟢 Green markers = Fiber (GPON) available
- 🔴 Red markers = Fiber not available
- 🟡 Yellow markers = Error or skipped points
- Click any marker to see detailed information
-
Export & Save
- Click "Export JSON" or "Export CSV" to download results
- Results are automatically saved to browser localStorage
- Reload the page to restore previous scan data
-
Retry Not Available Points
- After completing a scan, click "🔄 Retry Not Available" to re-scan points marked as "Not Available"
- Useful for checking if fiber coverage has been deployed to previously unavailable locations
- The system will show how many points to retry and update statistics
- Updated markers will reflect the new status (may become available or remain unavailable)
The Tunisie Telecom API requires a unique token for each request:
- Fetch server time from
getAppVersionendpoint - Extract and decode the timestamp
- Calculate token value using specific offsets
- Append a 10-character random string
- Each API request generates its own fresh token
async function getToken() {
const response = await fetch("https://gis.tunisietelecom.tn/rsm/RSMService.svc/getAppVersion");
const data = await response.json();
// ... token calculation logic
return token;
}
async function checkCoverage(lat, lng) {
// Generate fresh token for this specific request
const token = await getToken();
// ... make API call with token
}Coordinates are encoded before being sent to the API:
function codeCoordinates(x, y) {
const Ax = 100000.0, Ay = 100000.0;
const Bx = 123456.0, By = 654321.0;
return {
xCoded: (x * Ax) - Bx,
yCoded: (y * Ay) - By
};
}For each point in the grid:
- Encode the coordinates
- Send POST request to
TaghtiaUltimateendpoint - Check response for GPON availability
- Display result on map with appropriate color
- Add retry logic for failed requests
The application generates a grid of points based on:
- Latitude range (min to max)
- Longitude range (min to max)
- Step size (default 0.002° ≈ 200 meters)
Points are scanned sequentially with configurable delays between requests.
- HTML5 - Application structure
- CSS3 - Styling and responsive design
- JavaScript (ES6+) - Core logic and API integration
- Leaflet.js 1.9.4 - Interactive map library
- Leaflet.draw - Rectangle drawing for custom bounds
- Leaflet.heat - Heatmap visualization
- Bootstrap 5.3 - UI components and responsive grid
- OpenStreetMap - Free map tiles (no API key required)
This application uses the Tunisie Telecom coverage API (reverse-engineered):
Base URL: https://gis.tunisietelecom.tn/rsm/RSMService.svc/
Endpoints:
getAppVersion- Get server time for token generationTaghtiaUltimate- Check coverage for coordinates
GPON Availability Check:
if (result.taghtiaGPON.Code_taghtia == 200 &&
result.taghtiaGPON.Message_taghtia == "OK" &&
result.taghtiaGPON.Taghtia == "OUI") {
// GPON Fiber is available
}- ✅ Chrome/Edge (v90+)
- ✅ Firefox (v88+)
- ✅ Safari (v14+)
- ✅ Mobile browsers (iOS Safari, Chrome Mobile)
sfax-fiber-scanner/
├── index.html # Main HTML page with map and UI
├── style.css # Styles and responsive design
├── script.js # JavaScript logic and API integration
├── server.js # Local dev server with API proxy (Node.js)
├── package.json # npm dependencies and dev script
└── README.md # This fileThis project is inspired by and uses API information reverse-engineered from:
Caution
- The API used belongs to Tunisie Telecom and is not officially public
- This tool should be used responsibly and not for commercial purposes
- The author is not responsible for any misuse of this application
- Please respect rate limits and do not overload the API servers
- This is an unofficial tool and is not affiliated with Tunisie Telecom
- The official website for checking TT coverage: Taghtia
MIT License
Copyright (c) 2026
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.
Contributions are welcome! Please feel free to submit a Pull Request.
If you encounter any issues or have questions, please open an issue on GitHub.
Made with ❤️ for the Sfax community