This is working code for input KML files into leaflet map
// Load kml file
fetch('lotA.kml')
.then( res => res.text() )
.then( kmltext => {
// Create new kml overlay
parser = new DOMParser();
kml = parser.parseFromString(kmltext,"text/xml");
console.log(kml)
const track = new L.KML(kml)
map.addLayer(track)
// Adjust map to show the kml
const bounds = track.getBounds()
map.fitBounds( bounds )
})
fetch('lotB.kml')
.then( res => res.text() )
.then( kmltext => {
// Create new kml overlay
parser = new DOMParser();
kml = parser.parseFromString(kmltext,"text/xml");
console.log(kml)
const track = new L.KML(kml)
map.addLayer(track)
// Adjust map to show the kml
const bounds = track.getBounds()
map.fitBounds( bounds )
})
fetch('Schematic.kml')
.then( res => res.text() )
.then( kmltext => {
// Create new kml overlay
parser = new DOMParser();
kml = parser.parseFromString(kmltext,"text/xml");
console.log(kml)
const track = new L.KML(kml)
map.addLayer(track)
// Adjust map to show the kml
const bounds = track.getBounds()
map.fitBounds( bounds )
})
fetch('LotC.kml')
.then( res => res.text() )
.then( kmltext => {
// Create new kml overlay
parser = new DOMParser();
kml = parser.parseFromString(kmltext,"text/xml");
console.log(kml)
const track = new L.KML(kml)
map.addLayer(track)
// Adjust map to show the kml
const bounds = track.getBounds()
map.fitBounds( bounds )
})
fetch('LotD.kml')
.then( res => res.text() )
.then( kmltext => {
// Create new kml overlay
parser = new DOMParser();
kml = parser.parseFromString(kmltext,"text/xml");
console.log(kml)
const track = new L.KML(kml)
map.addLayer(track)
// Adjust map to show the kml
const bounds = track.getBounds()
map.fitBounds( bounds )
})
Is there a way to write this code shorter? I would like to use it for multiple KML layers.
1 Answer 1
This code is quite repetitive, and doesn’t adhere to the Don't Repeat Yourself principle.
One way to DRY it out is to abstract the latter promise callback to a separate function:
const addTrackAndBoundsFromKml = kmltext => {
// Create new kml overlay
const parser = new DOMParser();
kml = parser.parseFromString(kmltext,"text/xml");
const track = new L.KML(kml);
map.addLayer(track);
// Adjust map to show the kml
map.fitBounds( track.getBounds() );
};
Note that const
was added before the assignment of parser
to avoid a global variable from being created, and bounds
was eliminated because it was only used once. Also, semi-colons were added- while they are only required after a handful of statements, it could lead to errors if somehow whitespace got removed. It is a good habit to default to terminating lines with them.
Then use (a reference to) that function whenever it is needed:
// Load kml file
fetch('lotA.kml')
.then( res => res.text() )
.then( addTrackAndBoundsFromKml );
fetch('lotB.kml')
.then( res => res.text() )
.then( addTrackAndBoundsFromKml );
//etc...
This way if a change needed to happen in that function that parses the KML, adds the track layer and fits the bounds, it could be done in one place instead of each occurrence.
The file names could also be stored in an array and iterated over:
const files = ['lotA.kml', 'lotB.kml', 'Schematic.kml', 'lotC.kml', 'lotD.kml'];
for ( const file of files ) {
fetch(file)
.then( res => res.text() )
.then( addTrackAndBoundsFromKml );
}
It may not be useful but you could consider using Promise.all()
though the need to call the asynchronous .text()
method on each result might make that really complicated.
You could also consider using the ecmascript-8 feature async functions with the await
operator on the promises, as long as the browser requirements are sufficient.
Explore related questions
See similar questions with these tags.