forked from MapComplete/MapComplete
		
	
		
			
				
	
	
		
			114 lines
		
	
	
		
			No EOL
		
	
	
		
			4.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			114 lines
		
	
	
		
			No EOL
		
	
	
		
			4.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import {SubtleButton} from "../Base/SubtleButton";
 | 
						|
import Svg from "../../Svg";
 | 
						|
import Translations from "../i18n/Translations";
 | 
						|
import State from "../../State";
 | 
						|
import {Utils} from "../../Utils";
 | 
						|
import Combine from "../Base/Combine";
 | 
						|
import CheckBoxes from "../Input/Checkboxes";
 | 
						|
import {GeoOperations} from "../../Logic/GeoOperations";
 | 
						|
import Toggle from "../Input/Toggle";
 | 
						|
import Title from "../Base/Title";
 | 
						|
import FeaturePipeline from "../../Logic/FeatureSource/FeaturePipeline";
 | 
						|
import {UIEventSource} from "../../Logic/UIEventSource";
 | 
						|
import SimpleMetaTagger from "../../Logic/SimpleMetaTagger";
 | 
						|
import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig";
 | 
						|
import {BBox} from "../../Logic/BBox";
 | 
						|
 | 
						|
export class DownloadPanel extends Toggle {
 | 
						|
 | 
						|
    constructor() {
 | 
						|
        const state: {
 | 
						|
            featurePipeline: FeaturePipeline,
 | 
						|
            layoutToUse: LayoutConfig,
 | 
						|
            currentBounds: UIEventSource<BBox>
 | 
						|
        } = State.state
 | 
						|
 | 
						|
 | 
						|
        const t = Translations.t.general.download
 | 
						|
        const name = State.state.layoutToUse.id;
 | 
						|
 | 
						|
        const includeMetaToggle = new CheckBoxes([t.includeMetaData.Clone()])
 | 
						|
        const metaisIncluded = includeMetaToggle.GetValue().map(selected => selected.length > 0)
 | 
						|
 | 
						|
 | 
						|
        const buttonGeoJson = new SubtleButton(Svg.floppy_ui(),
 | 
						|
            new Combine([t.downloadGeojson.Clone().SetClass("font-bold"),
 | 
						|
                t.downloadGeoJsonHelper.Clone()]).SetClass("flex flex-col"))
 | 
						|
            .onClick(() => {
 | 
						|
                const geojson = DownloadPanel.getCleanGeoJson(state, metaisIncluded.data)
 | 
						|
                Utils.offerContentsAsDownloadableFile(JSON.stringify(geojson, null, "  "),
 | 
						|
                    `MapComplete_${name}_export_${new Date().toISOString().substr(0, 19)}.geojson`, {
 | 
						|
                        mimetype: "application/vnd.geo+json"
 | 
						|
                    });
 | 
						|
            })
 | 
						|
 | 
						|
 | 
						|
        const buttonCSV = new SubtleButton(Svg.floppy_ui(), new Combine(
 | 
						|
            [t.downloadCSV.Clone().SetClass("font-bold"),
 | 
						|
                t.downloadCSVHelper.Clone()]).SetClass("flex flex-col"))
 | 
						|
            .onClick(() => {
 | 
						|
                const geojson = DownloadPanel.getCleanGeoJson(state, metaisIncluded.data)
 | 
						|
                const csv = GeoOperations.toCSV(geojson.features)
 | 
						|
 | 
						|
                Utils.offerContentsAsDownloadableFile(csv,
 | 
						|
                    `MapComplete_${name}_export_${new Date().toISOString().substr(0, 19)}.csv`, {
 | 
						|
                        mimetype: "text/csv"
 | 
						|
                    });
 | 
						|
            })
 | 
						|
 | 
						|
        const downloadButtons = new Combine(
 | 
						|
            [new Title(t.title),
 | 
						|
                buttonGeoJson,
 | 
						|
                buttonCSV,
 | 
						|
                includeMetaToggle,
 | 
						|
                t.licenseInfo.Clone().SetClass("link-underline")])
 | 
						|
            .SetClass("w-full flex flex-col border-4 border-gray-300 rounded-3xl p-4")
 | 
						|
 | 
						|
        super(
 | 
						|
            downloadButtons,
 | 
						|
            t.noDataLoaded.Clone(),
 | 
						|
            state.featurePipeline.somethingLoaded)
 | 
						|
    }
 | 
						|
 | 
						|
    private static getCleanGeoJson(state: {
 | 
						|
        featurePipeline: FeaturePipeline,
 | 
						|
        currentBounds: UIEventSource<BBox>
 | 
						|
    }, includeMetaData: boolean) {
 | 
						|
 | 
						|
        const resultFeatures = []
 | 
						|
        const featureList = state.featurePipeline.GetAllFeaturesWithin(state.currentBounds.data);
 | 
						|
        for (const tile of featureList) {
 | 
						|
            for (const feature of tile) {
 | 
						|
                const cleaned = {
 | 
						|
                    type: feature.type,
 | 
						|
                    geometry: feature.geometry,
 | 
						|
                    properties: {...feature.properties}
 | 
						|
                }
 | 
						|
 | 
						|
                if (!includeMetaData) {
 | 
						|
                    for (const key in cleaned.properties) {
 | 
						|
                        if (key === "_lon" || key === "_lat") {
 | 
						|
                            continue;
 | 
						|
                        }
 | 
						|
                        if (key.startsWith("_")) {
 | 
						|
                            delete feature.properties[key]
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                const datedKeys = [].concat(SimpleMetaTagger.metatags.filter(tagging => tagging.includesDates).map(tagging => tagging.keys))
 | 
						|
                for (const key of datedKeys) {
 | 
						|
                    delete feature.properties[key]
 | 
						|
                }
 | 
						|
 | 
						|
                resultFeatures.push(feature)
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        return {
 | 
						|
            type: "FeatureCollection",
 | 
						|
            features: resultFeatures
 | 
						|
        }
 | 
						|
 | 
						|
    }
 | 
						|
} |