mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-16 17:31:24 +01:00
Geodata (#291)
* added geographic data to burgs CSV export * fixed projection problems in export added cell -> geojson export added a QGIS example style * adding routes data * adding river data * added PHP script to add random details to cells.
This commit is contained in:
parent
e743735e57
commit
263c2d6a3c
12 changed files with 857 additions and 199 deletions
BIN
.DS_Store
vendored
Normal file
BIN
.DS_Store
vendored
Normal file
Binary file not shown.
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
.DS_Store
|
||||||
|
wikidata
|
||||||
361
QGIS/Style_Biomes.qml
Normal file
361
QGIS/Style_Biomes.qml
Normal file
|
|
@ -0,0 +1,361 @@
|
||||||
|
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
|
||||||
|
<qgis styleCategories="Symbology" version="3.8.2-Zanzibar">
|
||||||
|
<renderer-v2 enableorderby="0" forceraster="0" attr="biome" symbollevels="0" type="categorizedSymbol">
|
||||||
|
<categories>
|
||||||
|
<category label="Marine" value="0" symbol="0" render="true"/>
|
||||||
|
<category label="Hot Desert" value="1" symbol="1" render="true"/>
|
||||||
|
<category label="Tundra" value="10" symbol="2" render="true"/>
|
||||||
|
<category label="Glacier" value="11" symbol="3" render="true"/>
|
||||||
|
<category label="Wetland" value="12" symbol="4" render="true"/>
|
||||||
|
<category label="Cold Desert" value="2" symbol="5" render="true"/>
|
||||||
|
<category label="Savanna" value="3" symbol="6" render="true"/>
|
||||||
|
<category label="Grassland" value="4" symbol="7" render="true"/>
|
||||||
|
<category label="Tropical Seasonal Forest" value="5" symbol="8" render="true"/>
|
||||||
|
<category label="Temperate Deciduous Forest" value="6" symbol="9" render="true"/>
|
||||||
|
<category label="Tropical Rainforest" value="7" symbol="10" render="true"/>
|
||||||
|
<category label="Temperate Rainforest" value="8" symbol="11" render="true"/>
|
||||||
|
<category label="Taiga" value="9" symbol="12" render="true"/>
|
||||||
|
<category label="" value="" symbol="13" render="true"/>
|
||||||
|
</categories>
|
||||||
|
<symbols>
|
||||||
|
<symbol name="0" alpha="1" clip_to_extent="1" force_rhr="0" type="fill">
|
||||||
|
<layer locked="0" pass="0" enabled="1" class="SimpleFill">
|
||||||
|
<prop k="border_width_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||||
|
<prop k="color" v="31,120,180,255"/>
|
||||||
|
<prop k="joinstyle" v="bevel"/>
|
||||||
|
<prop k="offset" v="0,0"/>
|
||||||
|
<prop k="offset_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||||
|
<prop k="offset_unit" v="MM"/>
|
||||||
|
<prop k="outline_color" v="31,120,180,255"/>
|
||||||
|
<prop k="outline_style" v="solid"/>
|
||||||
|
<prop k="outline_width" v="0.26"/>
|
||||||
|
<prop k="outline_width_unit" v="MM"/>
|
||||||
|
<prop k="style" v="solid"/>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option value="" name="name" type="QString"/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option value="collection" name="type" type="QString"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
<symbol name="1" alpha="1" clip_to_extent="1" force_rhr="0" type="fill">
|
||||||
|
<layer locked="0" pass="0" enabled="1" class="SimpleFill">
|
||||||
|
<prop k="border_width_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||||
|
<prop k="color" v="254,239,124,255"/>
|
||||||
|
<prop k="joinstyle" v="bevel"/>
|
||||||
|
<prop k="offset" v="0,0"/>
|
||||||
|
<prop k="offset_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||||
|
<prop k="offset_unit" v="MM"/>
|
||||||
|
<prop k="outline_color" v="254,239,124,255"/>
|
||||||
|
<prop k="outline_style" v="solid"/>
|
||||||
|
<prop k="outline_width" v="0.26"/>
|
||||||
|
<prop k="outline_width_unit" v="MM"/>
|
||||||
|
<prop k="style" v="solid"/>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option value="" name="name" type="QString"/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option value="collection" name="type" type="QString"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
<symbol name="10" alpha="1" clip_to_extent="1" force_rhr="0" type="fill">
|
||||||
|
<layer locked="0" pass="0" enabled="1" class="SimpleFill">
|
||||||
|
<prop k="border_width_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||||
|
<prop k="color" v="44,156,102,255"/>
|
||||||
|
<prop k="joinstyle" v="bevel"/>
|
||||||
|
<prop k="offset" v="0,0"/>
|
||||||
|
<prop k="offset_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||||
|
<prop k="offset_unit" v="MM"/>
|
||||||
|
<prop k="outline_color" v="44,156,102,255"/>
|
||||||
|
<prop k="outline_style" v="solid"/>
|
||||||
|
<prop k="outline_width" v="0.26"/>
|
||||||
|
<prop k="outline_width_unit" v="MM"/>
|
||||||
|
<prop k="style" v="solid"/>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option value="" name="name" type="QString"/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option value="collection" name="type" type="QString"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
<symbol name="11" alpha="1" clip_to_extent="1" force_rhr="0" type="fill">
|
||||||
|
<layer locked="0" pass="0" enabled="1" class="SimpleFill">
|
||||||
|
<prop k="border_width_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||||
|
<prop k="color" v="81,155,119,255"/>
|
||||||
|
<prop k="joinstyle" v="bevel"/>
|
||||||
|
<prop k="offset" v="0,0"/>
|
||||||
|
<prop k="offset_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||||
|
<prop k="offset_unit" v="MM"/>
|
||||||
|
<prop k="outline_color" v="81,155,119,255"/>
|
||||||
|
<prop k="outline_style" v="solid"/>
|
||||||
|
<prop k="outline_width" v="0.26"/>
|
||||||
|
<prop k="outline_width_unit" v="MM"/>
|
||||||
|
<prop k="style" v="solid"/>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option value="" name="name" type="QString"/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option value="collection" name="type" type="QString"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
<symbol name="12" alpha="1" clip_to_extent="1" force_rhr="0" type="fill">
|
||||||
|
<layer locked="0" pass="0" enabled="1" class="SimpleFill">
|
||||||
|
<prop k="border_width_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||||
|
<prop k="color" v="203,227,81,255"/>
|
||||||
|
<prop k="joinstyle" v="bevel"/>
|
||||||
|
<prop k="offset" v="0,0"/>
|
||||||
|
<prop k="offset_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||||
|
<prop k="offset_unit" v="MM"/>
|
||||||
|
<prop k="outline_color" v="203,227,81,255"/>
|
||||||
|
<prop k="outline_style" v="solid"/>
|
||||||
|
<prop k="outline_width" v="0.26"/>
|
||||||
|
<prop k="outline_width_unit" v="MM"/>
|
||||||
|
<prop k="style" v="solid"/>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option value="" name="name" type="QString"/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option value="collection" name="type" type="QString"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
<symbol name="13" alpha="1" clip_to_extent="1" force_rhr="0" type="fill">
|
||||||
|
<layer locked="0" pass="0" enabled="1" class="SimpleFill">
|
||||||
|
<prop k="border_width_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||||
|
<prop k="color" v="58,205,107,255"/>
|
||||||
|
<prop k="joinstyle" v="bevel"/>
|
||||||
|
<prop k="offset" v="0,0"/>
|
||||||
|
<prop k="offset_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||||
|
<prop k="offset_unit" v="MM"/>
|
||||||
|
<prop k="outline_color" v="35,35,35,255"/>
|
||||||
|
<prop k="outline_style" v="solid"/>
|
||||||
|
<prop k="outline_width" v="0.26"/>
|
||||||
|
<prop k="outline_width_unit" v="MM"/>
|
||||||
|
<prop k="style" v="solid"/>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option value="" name="name" type="QString"/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option value="collection" name="type" type="QString"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
<symbol name="2" alpha="1" clip_to_extent="1" force_rhr="0" type="fill">
|
||||||
|
<layer locked="0" pass="0" enabled="1" class="SimpleFill">
|
||||||
|
<prop k="border_width_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||||
|
<prop k="color" v="210,220,60,255"/>
|
||||||
|
<prop k="joinstyle" v="bevel"/>
|
||||||
|
<prop k="offset" v="0,0"/>
|
||||||
|
<prop k="offset_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||||
|
<prop k="offset_unit" v="MM"/>
|
||||||
|
<prop k="outline_color" v="210,220,60,255"/>
|
||||||
|
<prop k="outline_style" v="solid"/>
|
||||||
|
<prop k="outline_width" v="0.26"/>
|
||||||
|
<prop k="outline_width_unit" v="MM"/>
|
||||||
|
<prop k="style" v="solid"/>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option value="" name="name" type="QString"/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option value="collection" name="type" type="QString"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
<symbol name="3" alpha="1" clip_to_extent="1" force_rhr="0" type="fill">
|
||||||
|
<layer locked="0" pass="0" enabled="1" class="SimpleFill">
|
||||||
|
<prop k="border_width_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||||
|
<prop k="color" v="247,252,255,255"/>
|
||||||
|
<prop k="joinstyle" v="bevel"/>
|
||||||
|
<prop k="offset" v="0,0"/>
|
||||||
|
<prop k="offset_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||||
|
<prop k="offset_unit" v="MM"/>
|
||||||
|
<prop k="outline_color" v="247,252,255,255"/>
|
||||||
|
<prop k="outline_style" v="solid"/>
|
||||||
|
<prop k="outline_width" v="0.26"/>
|
||||||
|
<prop k="outline_width_unit" v="MM"/>
|
||||||
|
<prop k="style" v="solid"/>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option value="" name="name" type="QString"/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option value="collection" name="type" type="QString"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
<symbol name="4" alpha="1" clip_to_extent="1" force_rhr="0" type="fill">
|
||||||
|
<layer locked="0" pass="0" enabled="1" class="SimpleFill">
|
||||||
|
<prop k="border_width_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||||
|
<prop k="color" v="135,143,97,255"/>
|
||||||
|
<prop k="joinstyle" v="bevel"/>
|
||||||
|
<prop k="offset" v="0,0"/>
|
||||||
|
<prop k="offset_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||||
|
<prop k="offset_unit" v="MM"/>
|
||||||
|
<prop k="outline_color" v="135,143,97,255"/>
|
||||||
|
<prop k="outline_style" v="solid"/>
|
||||||
|
<prop k="outline_width" v="0.26"/>
|
||||||
|
<prop k="outline_width_unit" v="MM"/>
|
||||||
|
<prop k="style" v="solid"/>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option value="" name="name" type="QString"/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option value="collection" name="type" type="QString"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
<symbol name="5" alpha="1" clip_to_extent="1" force_rhr="0" type="fill">
|
||||||
|
<layer locked="0" pass="0" enabled="1" class="SimpleFill">
|
||||||
|
<prop k="border_width_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||||
|
<prop k="color" v="244,228,104,255"/>
|
||||||
|
<prop k="joinstyle" v="bevel"/>
|
||||||
|
<prop k="offset" v="0,0"/>
|
||||||
|
<prop k="offset_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||||
|
<prop k="offset_unit" v="MM"/>
|
||||||
|
<prop k="outline_color" v="244,228,104,255"/>
|
||||||
|
<prop k="outline_style" v="solid"/>
|
||||||
|
<prop k="outline_width" v="0.26"/>
|
||||||
|
<prop k="outline_width_unit" v="MM"/>
|
||||||
|
<prop k="style" v="solid"/>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option value="" name="name" type="QString"/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option value="collection" name="type" type="QString"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
<symbol name="6" alpha="1" clip_to_extent="1" force_rhr="0" type="fill">
|
||||||
|
<layer locked="0" pass="0" enabled="1" class="SimpleFill">
|
||||||
|
<prop k="border_width_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||||
|
<prop k="color" v="253,191,111,255"/>
|
||||||
|
<prop k="joinstyle" v="bevel"/>
|
||||||
|
<prop k="offset" v="0,0"/>
|
||||||
|
<prop k="offset_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||||
|
<prop k="offset_unit" v="MM"/>
|
||||||
|
<prop k="outline_color" v="253,191,111,255"/>
|
||||||
|
<prop k="outline_style" v="solid"/>
|
||||||
|
<prop k="outline_width" v="0.36"/>
|
||||||
|
<prop k="outline_width_unit" v="MM"/>
|
||||||
|
<prop k="style" v="solid"/>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option value="" name="name" type="QString"/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option value="collection" name="type" type="QString"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
<symbol name="7" alpha="1" clip_to_extent="1" force_rhr="0" type="fill">
|
||||||
|
<layer locked="0" pass="0" enabled="1" class="SimpleFill">
|
||||||
|
<prop k="border_width_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||||
|
<prop k="color" v="178,223,138,255"/>
|
||||||
|
<prop k="joinstyle" v="bevel"/>
|
||||||
|
<prop k="offset" v="0,0"/>
|
||||||
|
<prop k="offset_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||||
|
<prop k="offset_unit" v="MM"/>
|
||||||
|
<prop k="outline_color" v="178,223,138,255"/>
|
||||||
|
<prop k="outline_style" v="solid"/>
|
||||||
|
<prop k="outline_width" v="0.26"/>
|
||||||
|
<prop k="outline_width_unit" v="MM"/>
|
||||||
|
<prop k="style" v="solid"/>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option value="" name="name" type="QString"/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option value="collection" name="type" type="QString"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
<symbol name="8" alpha="1" clip_to_extent="1" force_rhr="0" type="fill">
|
||||||
|
<layer locked="0" pass="0" enabled="1" class="SimpleFill">
|
||||||
|
<prop k="border_width_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||||
|
<prop k="color" v="31,114,13,255"/>
|
||||||
|
<prop k="joinstyle" v="bevel"/>
|
||||||
|
<prop k="offset" v="0,0"/>
|
||||||
|
<prop k="offset_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||||
|
<prop k="offset_unit" v="MM"/>
|
||||||
|
<prop k="outline_color" v="31,114,13,255"/>
|
||||||
|
<prop k="outline_style" v="solid"/>
|
||||||
|
<prop k="outline_width" v="0.26"/>
|
||||||
|
<prop k="outline_width_unit" v="MM"/>
|
||||||
|
<prop k="style" v="solid"/>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option value="" name="name" type="QString"/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option value="collection" name="type" type="QString"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
<symbol name="9" alpha="1" clip_to_extent="1" force_rhr="0" type="fill">
|
||||||
|
<layer locked="0" pass="0" enabled="1" class="SimpleFill">
|
||||||
|
<prop k="border_width_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||||
|
<prop k="color" v="51,160,44,255"/>
|
||||||
|
<prop k="joinstyle" v="bevel"/>
|
||||||
|
<prop k="offset" v="0,0"/>
|
||||||
|
<prop k="offset_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||||
|
<prop k="offset_unit" v="MM"/>
|
||||||
|
<prop k="outline_color" v="51,160,44,255"/>
|
||||||
|
<prop k="outline_style" v="solid"/>
|
||||||
|
<prop k="outline_width" v="0.26"/>
|
||||||
|
<prop k="outline_width_unit" v="MM"/>
|
||||||
|
<prop k="style" v="solid"/>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option value="" name="name" type="QString"/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option value="collection" name="type" type="QString"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
</symbols>
|
||||||
|
<source-symbol>
|
||||||
|
<symbol name="0" alpha="1" clip_to_extent="1" force_rhr="0" type="fill">
|
||||||
|
<layer locked="0" pass="0" enabled="1" class="SimpleFill">
|
||||||
|
<prop k="border_width_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||||
|
<prop k="color" v="229,182,54,255"/>
|
||||||
|
<prop k="joinstyle" v="bevel"/>
|
||||||
|
<prop k="offset" v="0,0"/>
|
||||||
|
<prop k="offset_map_unit_scale" v="3x:0,0,0,0,0,0"/>
|
||||||
|
<prop k="offset_unit" v="MM"/>
|
||||||
|
<prop k="outline_color" v="35,35,35,255"/>
|
||||||
|
<prop k="outline_style" v="solid"/>
|
||||||
|
<prop k="outline_width" v="0.26"/>
|
||||||
|
<prop k="outline_width_unit" v="MM"/>
|
||||||
|
<prop k="style" v="solid"/>
|
||||||
|
<data_defined_properties>
|
||||||
|
<Option type="Map">
|
||||||
|
<Option value="" name="name" type="QString"/>
|
||||||
|
<Option name="properties"/>
|
||||||
|
<Option value="collection" name="type" type="QString"/>
|
||||||
|
</Option>
|
||||||
|
</data_defined_properties>
|
||||||
|
</layer>
|
||||||
|
</symbol>
|
||||||
|
</source-symbol>
|
||||||
|
<colorramp name="[source]" type="randomcolors"/>
|
||||||
|
<rotation/>
|
||||||
|
<sizescale/>
|
||||||
|
</renderer-v2>
|
||||||
|
<blendMode>0</blendMode>
|
||||||
|
<featureBlendMode>0</featureBlendMode>
|
||||||
|
<layerGeometryType>2</layerGeometryType>
|
||||||
|
</qgis>
|
||||||
81
QGIS/add_random_points.php
Normal file
81
QGIS/add_random_points.php
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$max_deviation = 0.2;
|
||||||
|
$max_abs = 0.02;
|
||||||
|
$min_distance = 0.1;
|
||||||
|
|
||||||
|
$iterations = 4;
|
||||||
|
|
||||||
|
if ($argc < 2 ) {
|
||||||
|
exit( "Usage: add_random_points.php <filename.json>\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: This script created a few cases of self-intersection that must be fixed manually
|
||||||
|
// in QGIS: Vector -> Geometry Tools -> Check Validity
|
||||||
|
|
||||||
|
$cells = json_decode(file_get_contents($argv[1]), true);
|
||||||
|
|
||||||
|
|
||||||
|
for ($i=0; $i<$iterations; $i++) {
|
||||||
|
$lookup = array();
|
||||||
|
|
||||||
|
foreach ($cells['features'] as &$cell) {
|
||||||
|
$points = $cell['geometry']['coordinates'][0];
|
||||||
|
|
||||||
|
$prev = null;
|
||||||
|
$newpoints = array();
|
||||||
|
|
||||||
|
foreach ($points as $point) {
|
||||||
|
if ($prev) {
|
||||||
|
$distance = sqrt(pow($prev[0] - $point[0], 2) + pow($prev[1] - $point[1], 2));
|
||||||
|
if ($distance == 0) continue;
|
||||||
|
|
||||||
|
if ($distance > $min_distance) {
|
||||||
|
$id_a = $prev[0]."-".$prev[1];
|
||||||
|
$id_b = $point[0]."-".$point[1];
|
||||||
|
|
||||||
|
if (isset($lookup[$id_a."--".$id_b])) {
|
||||||
|
$newpoints[] = $lookup[$id_a."--".$id_b];
|
||||||
|
} elseif (isset($lookup[$id_b."--".$id_a])) {
|
||||||
|
$newpoints[] = $lookup[$id_b."--".$id_a];
|
||||||
|
} else {
|
||||||
|
$x = ($prev[0]+$point[0])/2.0;
|
||||||
|
$y = ($prev[1]+$point[1])/2.0;
|
||||||
|
|
||||||
|
$r = mt_rand() / mt_getrandmax(); // 0-1
|
||||||
|
$r = ($r+1) / 2; // 0.5 - 1.0
|
||||||
|
|
||||||
|
// if we define dx=x2-x1 and dy=y2-y1, then the normals are (-dy, dx) and (dy, -dx).
|
||||||
|
$dx = $point[0] - $x;
|
||||||
|
$dy = $point[1] - $y;
|
||||||
|
|
||||||
|
if (mt_rand() / mt_getrandmax() < 0.5) {
|
||||||
|
$x_off = -$dy;
|
||||||
|
$y_off = $dx;
|
||||||
|
} else {
|
||||||
|
$x_off = $dy;
|
||||||
|
$y_off = -$dx;
|
||||||
|
}
|
||||||
|
|
||||||
|
$x_off *= $r * $max_deviation;
|
||||||
|
$x_off = max(min($x_off, $max_abs), $max_abs*-1);
|
||||||
|
|
||||||
|
$y_off *= $r * $max_deviation;
|
||||||
|
$y_off = max(min($y_off, $max_abs), $max_abs*-1);
|
||||||
|
|
||||||
|
$p = array($x + $x_off, $y + $y_off);
|
||||||
|
$lookup[$id_a."--".$id_b] = $p;
|
||||||
|
$newpoints[] = $p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$newpoints[] = $point;
|
||||||
|
$prev = $point;
|
||||||
|
}
|
||||||
|
$cell['geometry']['coordinates'][0] = $newpoints;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode($cells, JSON_PRETTY_PRINT);
|
||||||
|
|
||||||
|
?>
|
||||||
215
index.html
215
index.html
File diff suppressed because one or more lines are too long
48
main.js
48
main.js
|
|
@ -173,7 +173,7 @@ void function checkLoadParameters() {
|
||||||
|
|
||||||
function loadMapFromURL(maplink, random) {
|
function loadMapFromURL(maplink, random) {
|
||||||
const URL = decodeURIComponent(maplink);
|
const URL = decodeURIComponent(maplink);
|
||||||
|
|
||||||
fetch(URL, {method: 'GET', mode: 'cors'})
|
fetch(URL, {method: 'GET', mode: 'cors'})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
if(response.ok) return response.blob();
|
if(response.ok) return response.blob();
|
||||||
|
|
@ -188,7 +188,7 @@ function loadMapFromURL(maplink, random) {
|
||||||
function showUploadErrorMessage(error, URL, random) {
|
function showUploadErrorMessage(error, URL, random) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
alertMessage.innerHTML = `
|
alertMessage.innerHTML = `
|
||||||
Cannot load map from the <a href='${URL}' target='_blank'>link provided</a>.
|
Cannot load map from the <a href='${URL}' target='_blank'>link provided</a>.
|
||||||
${random?`A new random map is generated. `:''}
|
${random?`A new random map is generated. `:''}
|
||||||
Please ensure the linked file is reachable and CORS is allowed on server side`;
|
Please ensure the linked file is reachable and CORS is allowed on server side`;
|
||||||
$("#alert").dialog({title: "Loading error", width: 320, buttons: {OK: function() {$(this).dialog("close");}}});
|
$("#alert").dialog({title: "Loading error", width: 320, buttons: {OK: function() {$(this).dialog("close");}}});
|
||||||
|
|
@ -350,7 +350,7 @@ function applyDefaultNamesData() {
|
||||||
["Abim","Adjumani","Alebtong","Amolatar","Amuria","Amuru","Apac","Arua","Arusha","Babati","Baragoi","Bombo","Budaka","Bugembe","Bugiri","Buikwe","Bukedea","Bukoba","Bukomansimbi","Bukungu","Buliisa","Bundibugyo","Bungoma","Busembatya","Bushenyi","Busia","Busia","Busolwe","Butaleja","Butambala","Butere","Buwenge","Buyende","Dadaab","Dodoma","Dokolo","Eldoret","Elegu","Emali","Embu","Entebbe","Garissa","Gede","Gulu","Handeni","Hima","Hoima","Hola","Ibanda","Iganga","Iringa","Isingiro","Isiolo","Jinja","Kaabong","Kabale","Kaberamaido","Kabuyanda","Kabwohe","Kagadi","Kahama","Kajiado","Kakamega","Kakinga","Kakira","Kakiri","Kakuma","Kalangala","Kaliro","Kalisizo","Kalongo","Kalungu","Kampala","Kamuli","Kamwenge","Kanoni","Kanungu","Kapchorwa","Kapenguria","Kasese","Kasulu","Katakwi","Kayunga","Kericho","Keroka","Kiambu","Kibaale","Kibaha","Kibingo","Kiboga","Kibwezi","Kigoma","Kihiihi","Kilifi","Kira","Kiruhura","Kiryandongo","Kisii","Kisoro","Kisumu","Kitale","Kitgum","Kitui","Koboko","Korogwe","Kotido","Kumi","Kyazanga","Kyegegwa","Kyenjojo","Kyotera","Lamu","Langata","Lindi","Lodwar","Lokichoggio","Londiani","Loyangalani","Lugazi","Lukaya","Luweero","Lwakhakha","Lwengo","Lyantonde","Machakos","Mafinga","Makambako","Makindu","Malaba","Malindi","Manafwa","Mandera","Maralal","Marsabit","Masaka","Masindi","MasindiPort","Masulita","Matugga","Mayuge","Mbale","Mbarara","Mbeya","Meru","Mitooma","Mityana","Mombasa","Morogoro","Moroto","Moshi","Moyale","Moyo","Mpanda","Mpigi","Mpondwe","Mtwara","Mubende","Mukono","Mumias","Muranga","Musoma","Mutomo","Mutukula","Mwanza","Nagongera","Nairobi","Naivasha","Nakapiripirit","Nakaseke","Nakasongola","Nakuru","Namanga","Namayingo","Namutumba","Nansana","Nanyuki","Narok","Naromoru","Nebbi","Ngora","Njeru","Njombe","Nkokonjeru","Ntungamo","Nyahururu","Nyeri","Oyam","Pader","Paidha","Pakwach","Pallisa","Rakai","Ruiru","Rukungiri","Rwimi","Sanga","Sembabule","Shimoni","Shinyanga","Singida","Sironko","Songea","Soroti","Ssabagabo","Sumbawanga","Tabora","Takaungu","Tanga","Thika","Tororo","Tunduma","Vihiga","Voi","Wajir","Wakiso","Watamu","Webuye","Wobulenzi","Wote","Wundanyi","Yumbe","Zanzibar"],
|
["Abim","Adjumani","Alebtong","Amolatar","Amuria","Amuru","Apac","Arua","Arusha","Babati","Baragoi","Bombo","Budaka","Bugembe","Bugiri","Buikwe","Bukedea","Bukoba","Bukomansimbi","Bukungu","Buliisa","Bundibugyo","Bungoma","Busembatya","Bushenyi","Busia","Busia","Busolwe","Butaleja","Butambala","Butere","Buwenge","Buyende","Dadaab","Dodoma","Dokolo","Eldoret","Elegu","Emali","Embu","Entebbe","Garissa","Gede","Gulu","Handeni","Hima","Hoima","Hola","Ibanda","Iganga","Iringa","Isingiro","Isiolo","Jinja","Kaabong","Kabale","Kaberamaido","Kabuyanda","Kabwohe","Kagadi","Kahama","Kajiado","Kakamega","Kakinga","Kakira","Kakiri","Kakuma","Kalangala","Kaliro","Kalisizo","Kalongo","Kalungu","Kampala","Kamuli","Kamwenge","Kanoni","Kanungu","Kapchorwa","Kapenguria","Kasese","Kasulu","Katakwi","Kayunga","Kericho","Keroka","Kiambu","Kibaale","Kibaha","Kibingo","Kiboga","Kibwezi","Kigoma","Kihiihi","Kilifi","Kira","Kiruhura","Kiryandongo","Kisii","Kisoro","Kisumu","Kitale","Kitgum","Kitui","Koboko","Korogwe","Kotido","Kumi","Kyazanga","Kyegegwa","Kyenjojo","Kyotera","Lamu","Langata","Lindi","Lodwar","Lokichoggio","Londiani","Loyangalani","Lugazi","Lukaya","Luweero","Lwakhakha","Lwengo","Lyantonde","Machakos","Mafinga","Makambako","Makindu","Malaba","Malindi","Manafwa","Mandera","Maralal","Marsabit","Masaka","Masindi","MasindiPort","Masulita","Matugga","Mayuge","Mbale","Mbarara","Mbeya","Meru","Mitooma","Mityana","Mombasa","Morogoro","Moroto","Moshi","Moyale","Moyo","Mpanda","Mpigi","Mpondwe","Mtwara","Mubende","Mukono","Mumias","Muranga","Musoma","Mutomo","Mutukula","Mwanza","Nagongera","Nairobi","Naivasha","Nakapiripirit","Nakaseke","Nakasongola","Nakuru","Namanga","Namayingo","Namutumba","Nansana","Nanyuki","Narok","Naromoru","Nebbi","Ngora","Njeru","Njombe","Nkokonjeru","Ntungamo","Nyahururu","Nyeri","Oyam","Pader","Paidha","Pakwach","Pallisa","Rakai","Ruiru","Rukungiri","Rwimi","Sanga","Sembabule","Shimoni","Shinyanga","Singida","Sironko","Songea","Soroti","Ssabagabo","Sumbawanga","Tabora","Takaungu","Tanga","Thika","Tororo","Tunduma","Vihiga","Voi","Wajir","Wakiso","Watamu","Webuye","Wobulenzi","Wote","Wundanyi","Yumbe","Zanzibar"],
|
||||||
["An Khe","An Nhon","Ayun Pa","Ba Don","Ba Ria","Bac Giang","Bac Kan","Bac Lieu","Bac Ninh","Bao Loc","Ben Cat","Ben Tre","Bien Hoa","Bim Son","Binh Long","Binh Minh","Buon Ho","Buon Ma Thuot","Ca Mau","Cai Lay","Cam Pha","Cam Ranh","Can Tho","Cao Bang","Cao Lanh","Chau Doc","Chi Linh","Cua Lo","Da Lat","Da Nang","Di An","Dien Ban","Dien Bien Phu","Dong Ha","Dong Hoi","Dong Trieu","Duyen Hai","Gia Nghia","Gia Rai","Go Cong","Ha Giang","Ha Long","Ha Noi","Ha Tinh","Hai Duong","Hai Phong","Hoa Binh","Hoang Mai","Hoi An","Hong Linh","Hong Ngu","Hue","Hung Yen","Huong Thuy","Huong Tra","Kien Tuong","Kon Tum","Ky Anh","La Gi","Lai Chau","Lang Son","Lao Cai","Long Khanh","Long My","Long Xuyen","Mong Cai","Muong Lay","My Hao","My Tho","Nam Dinh","Nga Bay","Nga Nam","Nghia Lo","Nha Trang","Ninh Binh","Ninh Hoa","Phan Rang Thap Cham","Phan Thiet","Pho Yen","Phu Ly","Phu My","Phu Tho","Phuoc Long","Pleiku","Quang Ngai","Quang Tri","Quang Yen","Quy Nhon","Rach Gia","Sa Dec","Sam Son","Soc Trang","Son La","Son Tay","Song Cau","Song Cong","Tam Diep","Tam Ky","Tan An","Tan Chau","Tan Uyen","Tay Ninh","Thai Binh","Thai Hoa","Thai Nguyen","Thanh Hoa","Thu Dau Mot","Thuan An","Tra Vinh","Tu Son","Tuy Hoa","Tuyen Quang","Uong Bi","Vi Thanh","Viet Tri","Vinh","Vinh Chau","Vinh Long","Vinh Yen","Vung Tau","Yen Bai"],
|
["An Khe","An Nhon","Ayun Pa","Ba Don","Ba Ria","Bac Giang","Bac Kan","Bac Lieu","Bac Ninh","Bao Loc","Ben Cat","Ben Tre","Bien Hoa","Bim Son","Binh Long","Binh Minh","Buon Ho","Buon Ma Thuot","Ca Mau","Cai Lay","Cam Pha","Cam Ranh","Can Tho","Cao Bang","Cao Lanh","Chau Doc","Chi Linh","Cua Lo","Da Lat","Da Nang","Di An","Dien Ban","Dien Bien Phu","Dong Ha","Dong Hoi","Dong Trieu","Duyen Hai","Gia Nghia","Gia Rai","Go Cong","Ha Giang","Ha Long","Ha Noi","Ha Tinh","Hai Duong","Hai Phong","Hoa Binh","Hoang Mai","Hoi An","Hong Linh","Hong Ngu","Hue","Hung Yen","Huong Thuy","Huong Tra","Kien Tuong","Kon Tum","Ky Anh","La Gi","Lai Chau","Lang Son","Lao Cai","Long Khanh","Long My","Long Xuyen","Mong Cai","Muong Lay","My Hao","My Tho","Nam Dinh","Nga Bay","Nga Nam","Nghia Lo","Nha Trang","Ninh Binh","Ninh Hoa","Phan Rang Thap Cham","Phan Thiet","Pho Yen","Phu Ly","Phu My","Phu Tho","Phuoc Long","Pleiku","Quang Ngai","Quang Tri","Quang Yen","Quy Nhon","Rach Gia","Sa Dec","Sam Son","Soc Trang","Son La","Son Tay","Song Cau","Song Cong","Tam Diep","Tam Ky","Tan An","Tan Chau","Tan Uyen","Tay Ninh","Thai Binh","Thai Hoa","Thai Nguyen","Thanh Hoa","Thu Dau Mot","Thuan An","Tra Vinh","Tu Son","Tuy Hoa","Tuyen Quang","Uong Bi","Vi Thanh","Viet Tri","Vinh","Vinh Chau","Vinh Long","Vinh Yen","Vung Tau","Yen Bai"],
|
||||||
["Chaiwan", "Chekham", "Cheungshawan", "Chingchung", "Chinghoi", "Chingsen", "Chingshing", "Chiunam", "Chiuon", "Chiuyeung", "Chiyuen", "Choihung", "Chuehoi", "Chuiman", "Chungfa", "Chungfu", "Chungsan", "Chunguktsuen", "Dakhing", "Daopo", "Daumun", "Dingwu", "Dinpak", "Donggun", "Dongyuen", "Duenchau", "Fachau", "Fado", "Fanling", "Fatgong", "Fatshan", "Fotan", "Fuktien", "Fumun", "Funggong", "Funghoi", "Fungshun", "Fungtei", "Gamtin", "Gochau", "Goming", "Gonghoi", "Gongshing", "Goyiu", "Hanghau", "Hangmei", "Hashan", "Hengfachuen", "Hengon", "Heungchau", "Heunggong", "Heungkiu", "Hingning", "Hohfuktong", "Hoichue", "Hoifung", "Hoiping", "Hokong", "Hokshan", "Homantin", "Hotin", "Hoyuen", "Hunghom", "Hungshuikiu", "Jiuling", "Kamping", "Kamsheung", "Kamwan", "Kaulongtong", "Keilun", "Kinon", "Kinsang", "Kityeung", "Kongmun", "Kukgong", "Kwaifong", "Kwaihing", "Kwongchau", "Kwongling", "Kwongming", "Kwuntong", "Laichikok", "Laiking", "Laiwan", "Lamtei", "Lamtin", "Leitung", "Leungking", "Limkong", "Linchau", "Linnam", "Linping", "Linshan", "Loding", "Lokcheong", "Lokfu", "Lokmachau", "Longchuen", "Longgong", "Longmun", "Longping", "Longwa", "Longwu", "Lowu", "Luichau", "Lukfung", "Lukho", "Lungmun", "Macheung", "Maliushui", "Maonshan", "Mauming", "Maunam", "Meifoo", "Mingkum", "Mogong", "Mongkok", "Muichau", "Muigong", "Muiyuen", "Naiwai", "Namcheong", "Namhoi", "Namhong", "Namo", "Namsha", "Namshan", "Nganwai", "Ngchuen", "Ngoumun", "Ngwa", "Nngautaukok", "Onting", "Pakwun", "Paotoishan", "Pingshan", "Pingyuen", "Poklo", "Polam", "Pongon", "Poning", "Potau", "Puito", "Punyue", "Saiwanho", "Saiyingpun", "Samshing", "Samshui", "Samtsen", "Samyuenlei", "Sanfung", "Sanhing", "Sanhui", "Sanwai", "Sanwui", "Seiwui", "Shamshuipo", "Shanmei", "Shantau", "Shatin", "Shatinwai", "Shaukeiwan", "Shauking", "Shekkipmei", "Shekmun", "Shekpai", "Sheungshui", "Shingkui", "Shiuhing", "Shundak", "Shunyi", "Shupinwai", "Simshing", "Siuhei", "Siuhong", "Siukwan", "Siulun", "Suikai", "Taihing", "Taikoo", "Taipo", "Taishuihang", "Taiwai", "Taiwo", "Taiwohau", "Tinhau", "Tinho", "Tinking", "Tinshuiwai", "Tiukengleng", "Toishan", "Tongfong", "Tonglowan", "Tsakyoochung", "Tsamgong", "Tsangshing", "Tseungkwano", "Tsihing", "Tsimshatsui", "Tsinggong", "Tsingshantsuen", "Tsingwun", "Tsingyi", "Tsingyuen", "Tsiuchau", "Tsuenshekshan", "Tsuenwan", "Tuenmun", "Tungchung", "Waichap", "Waichau", "Waidong", "Wailoi", "Waishing", "Waiyeung", "Wanchai", "Wanfau", "Wanon", "Wanshing", "Wingon", "Wongchukhang", "Wongpo", "Wongtaisin", "Woping", "Wukaisha", "Yano", "Yaumatei", "Yauoi", "Yautong", "Yenfa", "Yeungchun", "Yeungdong", "Yeunggong", "Yeungsai", "Yeungshan", "Yimtin", "Yingdak", "Yiuping", "Yongshing", "Yongyuen", "Yuenlong", "Yuenshing", "Yuetsau", "Yuknam", "Yunping", "Yuyuen"],
|
["Chaiwan", "Chekham", "Cheungshawan", "Chingchung", "Chinghoi", "Chingsen", "Chingshing", "Chiunam", "Chiuon", "Chiuyeung", "Chiyuen", "Choihung", "Chuehoi", "Chuiman", "Chungfa", "Chungfu", "Chungsan", "Chunguktsuen", "Dakhing", "Daopo", "Daumun", "Dingwu", "Dinpak", "Donggun", "Dongyuen", "Duenchau", "Fachau", "Fado", "Fanling", "Fatgong", "Fatshan", "Fotan", "Fuktien", "Fumun", "Funggong", "Funghoi", "Fungshun", "Fungtei", "Gamtin", "Gochau", "Goming", "Gonghoi", "Gongshing", "Goyiu", "Hanghau", "Hangmei", "Hashan", "Hengfachuen", "Hengon", "Heungchau", "Heunggong", "Heungkiu", "Hingning", "Hohfuktong", "Hoichue", "Hoifung", "Hoiping", "Hokong", "Hokshan", "Homantin", "Hotin", "Hoyuen", "Hunghom", "Hungshuikiu", "Jiuling", "Kamping", "Kamsheung", "Kamwan", "Kaulongtong", "Keilun", "Kinon", "Kinsang", "Kityeung", "Kongmun", "Kukgong", "Kwaifong", "Kwaihing", "Kwongchau", "Kwongling", "Kwongming", "Kwuntong", "Laichikok", "Laiking", "Laiwan", "Lamtei", "Lamtin", "Leitung", "Leungking", "Limkong", "Linchau", "Linnam", "Linping", "Linshan", "Loding", "Lokcheong", "Lokfu", "Lokmachau", "Longchuen", "Longgong", "Longmun", "Longping", "Longwa", "Longwu", "Lowu", "Luichau", "Lukfung", "Lukho", "Lungmun", "Macheung", "Maliushui", "Maonshan", "Mauming", "Maunam", "Meifoo", "Mingkum", "Mogong", "Mongkok", "Muichau", "Muigong", "Muiyuen", "Naiwai", "Namcheong", "Namhoi", "Namhong", "Namo", "Namsha", "Namshan", "Nganwai", "Ngchuen", "Ngoumun", "Ngwa", "Nngautaukok", "Onting", "Pakwun", "Paotoishan", "Pingshan", "Pingyuen", "Poklo", "Polam", "Pongon", "Poning", "Potau", "Puito", "Punyue", "Saiwanho", "Saiyingpun", "Samshing", "Samshui", "Samtsen", "Samyuenlei", "Sanfung", "Sanhing", "Sanhui", "Sanwai", "Sanwui", "Seiwui", "Shamshuipo", "Shanmei", "Shantau", "Shatin", "Shatinwai", "Shaukeiwan", "Shauking", "Shekkipmei", "Shekmun", "Shekpai", "Sheungshui", "Shingkui", "Shiuhing", "Shundak", "Shunyi", "Shupinwai", "Simshing", "Siuhei", "Siuhong", "Siukwan", "Siulun", "Suikai", "Taihing", "Taikoo", "Taipo", "Taishuihang", "Taiwai", "Taiwo", "Taiwohau", "Tinhau", "Tinho", "Tinking", "Tinshuiwai", "Tiukengleng", "Toishan", "Tongfong", "Tonglowan", "Tsakyoochung", "Tsamgong", "Tsangshing", "Tseungkwano", "Tsihing", "Tsimshatsui", "Tsinggong", "Tsingshantsuen", "Tsingwun", "Tsingyi", "Tsingyuen", "Tsiuchau", "Tsuenshekshan", "Tsuenwan", "Tuenmun", "Tungchung", "Waichap", "Waichau", "Waidong", "Wailoi", "Waishing", "Waiyeung", "Wanchai", "Wanfau", "Wanon", "Wanshing", "Wingon", "Wongchukhang", "Wongpo", "Wongtaisin", "Woping", "Wukaisha", "Yano", "Yaumatei", "Yauoi", "Yautong", "Yenfa", "Yeungchun", "Yeungdong", "Yeunggong", "Yeungsai", "Yeungshan", "Yimtin", "Yingdak", "Yiuping", "Yongshing", "Yongyuen", "Yuenlong", "Yuenshing", "Yuetsau", "Yuknam", "Yunping", "Yuyuen"],
|
||||||
["Adaatsag", "Airag", "Alag Erdene", "Altai", "Altanshiree", "Altantsogts", "Arbulag", "Baatsagaan", "Batnorov", "Batshireet", "Battsengel", "Bayan Adarga", "Bayan Agt", "Bayanbulag", "Bayandalai", "Bayandun", "Bayangovi", "Bayanjargalan", "Bayankhongor", "Bayankhutag", "Bayanlig", "Bayanmonkh", "Bayannuur", "Bayan Ondor", "Bayan Ovoo", "Bayantal", "Bayantsagaan", "Bayantumen", "Bayan Uul", "Bayanzurkh", "Berkh", "Biger", "Binder", "Bogd", "Bombogor", "Bor Ondor", "Bugat", "Bulgan", "Buregkhangai", "Burentogtokh", "Buutsagaan", "Buyant", "Chandmani", "Chandmani Ondor", "Choibalsan", "Chuluunkhoroot", "Chuluut", "Dadal", "Dalanjargalan", "Dalanzadgad", "Darkhan", "Darvi", "Dashbalbar", "Dashinchilen", "Delger", "Delgerekh", "Delgerkhaan", "Delgerkhangai", "Delgertsogt", "Deluun", "Deren", "Dorgon", "Duut", "Erdene", "Erdenebulgan", "Erdeneburen", "Erdenedalai", "Erdenemandal", "Erdenetsogt", "Galshar", "Galt", "Galuut", "Govi Ugtaal", "Gurvan", "Gurvanbulag", "Gurvansaikhan", "Gurvanzagal", "Ikhkhet", "Ikh Tamir", "Ikh Uul", "Jargalan", "Jargalant", "Jargaltkhaan", "Jinst", "Khairkhan", "Khalhgol", "Khaliun", "Khanbogd", "Khangai", "Khangal", "Khankh", "Khankhongor", "Khashaat", "Khatanbulag", "Khatgal", "Kherlen", "Khishig Ondor", "Khokh", "Kholonbuir", "Khongor", "Khotont", "Khovd", "Khovsgol", "Khuld", "Khureemaral", "Khurmen", "Khutag Ondor", "Luus", "Mandakh", "Mandal Ovoo", "Mankhan", "Manlai", "Matad", "Mogod", "Monkhkhairkhan", "Moron", "Most", "Myangad", "Nogoonnuur", "Nomgon", "Norovlin", "Noyon", "Ogii", "Olgii", "Olziit", "Omnodelger", "Ondorkhaan", "Ondorshil", "Ondor Ulaan", "Orgon", "Orkhon", "Rashaant", "Renchinlkhumbe", "Sagsai", "Saikhan", "Saikhandulaan", "Saikhan Ovoo", "Sainshand", "Saintsagaan", "Selenge", "Sergelen", "Sevrei", "Sharga", "Sharyngol", "Shine Ider", "Shinejinst", "Shiveegovi", "Sumber", "Taishir", "Tarialan", "Tariat", "Teshig", "Togrog", "Tolbo", "Tomorbulag", "Tonkhil", "Tosontsengel", "Tsagaandelger", "Tsagaannuur", "Tsagaan Ovoo", "Tsagaan Uur", "Tsakhir", "Tseel", "Tsengel", "Tsenkher", "Tsenkhermandal", "Tsetseg", "Tsetserleg", "Tsogt", "Tsogt Ovoo", "Tsogttsetsii", "Tunel", "Tuvshruulekh", "Ulaanbadrakh", "Ulaankhus", "Ulaan Uul", "Uyench", "Yesonbulag", "Zag", "Zamyn Uud", "Zereg"]
|
["Adaatsag", "Airag", "Alag Erdene", "Altai", "Altanshiree", "Altantsogts", "Arbulag", "Baatsagaan", "Batnorov", "Batshireet", "Battsengel", "Bayan Adarga", "Bayan Agt", "Bayanbulag", "Bayandalai", "Bayandun", "Bayangovi", "Bayanjargalan", "Bayankhongor", "Bayankhutag", "Bayanlig", "Bayanmonkh", "Bayannuur", "Bayan Ondor", "Bayan Ovoo", "Bayantal", "Bayantsagaan", "Bayantumen", "Bayan Uul", "Bayanzurkh", "Berkh", "Biger", "Binder", "Bogd", "Bombogor", "Bor Ondor", "Bugat", "Bulgan", "Buregkhangai", "Burentogtokh", "Buutsagaan", "Buyant", "Chandmani", "Chandmani Ondor", "Choibalsan", "Chuluunkhoroot", "Chuluut", "Dadal", "Dalanjargalan", "Dalanzadgad", "Darkhan", "Darvi", "Dashbalbar", "Dashinchilen", "Delger", "Delgerekh", "Delgerkhaan", "Delgerkhangai", "Delgertsogt", "Deluun", "Deren", "Dorgon", "Duut", "Erdene", "Erdenebulgan", "Erdeneburen", "Erdenedalai", "Erdenemandal", "Erdenetsogt", "Galshar", "Galt", "Galuut", "Govi Ugtaal", "Gurvan", "Gurvanbulag", "Gurvansaikhan", "Gurvanzagal", "Ikhkhet", "Ikh Tamir", "Ikh Uul", "Jargalan", "Jargalant", "Jargaltkhaan", "Jinst", "Khairkhan", "Khalhgol", "Khaliun", "Khanbogd", "Khangai", "Khangal", "Khankh", "Khankhongor", "Khashaat", "Khatanbulag", "Khatgal", "Kherlen", "Khishig Ondor", "Khokh", "Kholonbuir", "Khongor", "Khotont", "Khovd", "Khovsgol", "Khuld", "Khureemaral", "Khurmen", "Khutag Ondor", "Luus", "Mandakh", "Mandal Ovoo", "Mankhan", "Manlai", "Matad", "Mogod", "Monkhkhairkhan", "Moron", "Most", "Myangad", "Nogoonnuur", "Nomgon", "Norovlin", "Noyon", "Ogii", "Olgii", "Olziit", "Omnodelger", "Ondorkhaan", "Ondorshil", "Ondor Ulaan", "Orgon", "Orkhon", "Rashaant", "Renchinlkhumbe", "Sagsai", "Saikhan", "Saikhandulaan", "Saikhan Ovoo", "Sainshand", "Saintsagaan", "Selenge", "Sergelen", "Sevrei", "Sharga", "Sharyngol", "Shine Ider", "Shinejinst", "Shiveegovi", "Sumber", "Taishir", "Tarialan", "Tariat", "Teshig", "Togrog", "Tolbo", "Tomorbulag", "Tonkhil", "Tosontsengel", "Tsagaandelger", "Tsagaannuur", "Tsagaan Ovoo", "Tsagaan Uur", "Tsakhir", "Tseel", "Tsengel", "Tsenkher", "Tsenkhermandal", "Tsetseg", "Tsetserleg", "Tsogt", "Tsogt Ovoo", "Tsogttsetsii", "Tunel", "Tuvshruulekh", "Ulaanbadrakh", "Ulaankhus", "Ulaan Uul", "Uyench", "Yesonbulag", "Zag", "Zamyn Uud", "Zereg"]
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -441,10 +441,10 @@ function applyDefaultStyle() {
|
||||||
|
|
||||||
// heightmap style
|
// heightmap style
|
||||||
terrs.attr("opacity", null).attr("filter", null).attr("mask", "url(#land)").attr("stroke", "none");
|
terrs.attr("opacity", null).attr("filter", null).attr("mask", "url(#land)").attr("stroke", "none");
|
||||||
const changed = styleHeightmapSchemeInput.value !== "bright" ||
|
const changed = styleHeightmapSchemeInput.value !== "bright" ||
|
||||||
styleHeightmapTerracingInput.value != 0 ||
|
styleHeightmapTerracingInput.value != 0 ||
|
||||||
styleHeightmapSkipInput.value != 5 ||
|
styleHeightmapSkipInput.value != 5 ||
|
||||||
styleHeightmapSimplificationInput.value != 0 ||
|
styleHeightmapSimplificationInput.value != 0 ||
|
||||||
styleHeightmapCurveInput.value != 0;
|
styleHeightmapCurveInput.value != 0;
|
||||||
styleHeightmapSchemeInput.value = "bright";
|
styleHeightmapSchemeInput.value = "bright";
|
||||||
styleHeightmapTerracingInput.value = styleHeightmapTerracingOutput.value = 0;
|
styleHeightmapTerracingInput.value = styleHeightmapTerracingOutput.value = 0;
|
||||||
|
|
@ -473,7 +473,7 @@ function applyDefaultStyle() {
|
||||||
labels.select("#states").attr("fill", "#3e3e4b").attr("opacity", 1).attr("stroke", "#3a3a3a").attr("stroke-width", 0).attr("font-family", "Almendra SC").attr("data-font", "Almendra+SC").attr("font-size", stateLabelSize).attr("data-size", stateLabelSize).attr("filter", null);
|
labels.select("#states").attr("fill", "#3e3e4b").attr("opacity", 1).attr("stroke", "#3a3a3a").attr("stroke-width", 0).attr("font-family", "Almendra SC").attr("data-font", "Almendra+SC").attr("font-size", stateLabelSize).attr("data-size", stateLabelSize).attr("filter", null);
|
||||||
labels.select("#addedLabels").attr("fill", "#3e3e4b").attr("opacity", 1).attr("stroke", "#3a3a3a").attr("stroke-width", 0).attr("font-family", "Almendra SC").attr("data-font", "Almendra+SC").attr("font-size", 18).attr("data-size", 18).attr("filter", null);
|
labels.select("#addedLabels").attr("fill", "#3e3e4b").attr("opacity", 1).attr("stroke", "#3a3a3a").attr("stroke-width", 0).attr("font-family", "Almendra SC").attr("data-font", "Almendra+SC").attr("font-size", 18).attr("data-size", 18).attr("filter", null);
|
||||||
invokeActiveZooming();
|
invokeActiveZooming();
|
||||||
|
|
||||||
fogging.attr("opacity", .8).attr("fill", "#000000").attr("stroke-width", 5);
|
fogging.attr("opacity", .8).attr("fill", "#000000").attr("stroke-width", 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -481,7 +481,7 @@ function showWelcomeMessage() {
|
||||||
const link = 'https://www.reddit.com/r/FantasyMapGenerator/comments/cxu1c5/update_new_version_is_published_v_10'; // announcement on Reddit
|
const link = 'https://www.reddit.com/r/FantasyMapGenerator/comments/cxu1c5/update_new_version_is_published_v_10'; // announcement on Reddit
|
||||||
alertMessage.innerHTML = `The Fantasy Map Generator is updated up to version <b>${version}</b>.
|
alertMessage.innerHTML = `The Fantasy Map Generator is updated up to version <b>${version}</b>.
|
||||||
|
|
||||||
This version is compatible with versions 0.8b and 0.9b, but not with older .map files.
|
This version is compatible with versions 0.8b and 0.9b, but not with older .map files.
|
||||||
Please use an <a href='https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Changelog' target='_blank'>archived version</a> to open old files.
|
Please use an <a href='https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Changelog' target='_blank'>archived version</a> to open old files.
|
||||||
|
|
||||||
<ul><a href=${link} target='_blank'>Main changes:</a>
|
<ul><a href=${link} target='_blank'>Main changes:</a>
|
||||||
|
|
@ -504,8 +504,8 @@ function showWelcomeMessage() {
|
||||||
<li>Desktop version (see <a href='https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Q&A#is-there-a-desktop-version' target='_blank'>here)</a></li>
|
<li>Desktop version (see <a href='https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Q&A#is-there-a-desktop-version' target='_blank'>here)</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>Join our <a href='https://www.reddit.com/r/FantasyMapGenerator' target='_blank'>Reddit community</a> and
|
<p>Join our <a href='https://www.reddit.com/r/FantasyMapGenerator' target='_blank'>Reddit community</a> and
|
||||||
<a href='https://discordapp.com/invite/X7E84HU' target='_blank'>Discord server</a>
|
<a href='https://discordapp.com/invite/X7E84HU' target='_blank'>Discord server</a>
|
||||||
to ask questions, share maps, discuss the Generator, report bugs and propose new features.</p>
|
to ask questions, share maps, discuss the Generator, report bugs and propose new features.</p>
|
||||||
|
|
||||||
<p>Thanks for all supporters on <a href='https://www.patreon.com/azgaar' target='_blank'>Patreon</a>!</i></p>`;
|
<p>Thanks for all supporters on <a href='https://www.patreon.com/azgaar' target='_blank'>Patreon</a>!</i></p>`;
|
||||||
|
|
@ -663,17 +663,17 @@ function generate() {
|
||||||
generatePrecipitation();
|
generatePrecipitation();
|
||||||
reGraph();
|
reGraph();
|
||||||
drawCoastline();
|
drawCoastline();
|
||||||
|
|
||||||
elevateLakes();
|
elevateLakes();
|
||||||
Rivers.generate();
|
Rivers.generate();
|
||||||
defineBiomes();
|
defineBiomes();
|
||||||
|
|
||||||
rankCells();
|
rankCells();
|
||||||
Cultures.generate();
|
Cultures.generate();
|
||||||
Cultures.expand();
|
Cultures.expand();
|
||||||
BurgsAndStates.generate();
|
BurgsAndStates.generate();
|
||||||
Religions.generate();
|
Religions.generate();
|
||||||
|
|
||||||
drawStates();
|
drawStates();
|
||||||
drawBorders();
|
drawBorders();
|
||||||
BurgsAndStates.drawStateLabels();
|
BurgsAndStates.drawStateLabels();
|
||||||
|
|
@ -702,7 +702,7 @@ function generate() {
|
||||||
}, position: {my: "center", at: "center", of: "svg"}
|
}, position: {my: "center", at: "center", of: "svg"}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate map seed (string!) or get it from URL searchParams
|
// generate map seed (string!) or get it from URL searchParams
|
||||||
|
|
@ -738,7 +738,7 @@ function calculateVoronoi(graph, points) {
|
||||||
const allPoints = points.concat(grid.boundary);
|
const allPoints = points.concat(grid.boundary);
|
||||||
const delaunay = Delaunator.from(allPoints);
|
const delaunay = Delaunator.from(allPoints);
|
||||||
console.timeEnd("calculateDelaunay");
|
console.timeEnd("calculateDelaunay");
|
||||||
|
|
||||||
console.time("calculateVoronoi");
|
console.time("calculateVoronoi");
|
||||||
const voronoi = Voronoi(delaunay, allPoints, n);
|
const voronoi = Voronoi(delaunay, allPoints, n);
|
||||||
graph.cells = voronoi.cells;
|
graph.cells = voronoi.cells;
|
||||||
|
|
@ -892,7 +892,7 @@ function generatePrecipitation() {
|
||||||
// x1 = 70-90 latitude: dry all year (sinking zone)
|
// x1 = 70-90 latitude: dry all year (sinking zone)
|
||||||
}
|
}
|
||||||
const lalitudeModifier = [4,2,2,2,1,1,2,2,2,2,3,3,2,2,1,1,1,0.5]; // by 5d step
|
const lalitudeModifier = [4,2,2,2,1,1,2,2,2,2,3,3,2,2,1,1,1,0.5]; // by 5d step
|
||||||
|
|
||||||
// difine wind directions based on cells latitude and prevailing winds there
|
// difine wind directions based on cells latitude and prevailing winds there
|
||||||
d3.range(0, cells.i.length, cellsX).forEach(function(c, i) {
|
d3.range(0, cells.i.length, cellsX).forEach(function(c, i) {
|
||||||
const lat = mapCoordinates.latN - i / cellsY * mapCoordinates.latT;
|
const lat = mapCoordinates.latN - i / cellsY * mapCoordinates.latT;
|
||||||
|
|
@ -904,7 +904,7 @@ function generatePrecipitation() {
|
||||||
if (winds[tier] > 100 && winds[tier] < 260) northerly++;
|
if (winds[tier] > 100 && winds[tier] < 260) northerly++;
|
||||||
else if (winds[tier] > 280 || winds[tier] < 80) southerly++;
|
else if (winds[tier] > 280 || winds[tier] < 80) southerly++;
|
||||||
});
|
});
|
||||||
|
|
||||||
// distribute winds by direction
|
// distribute winds by direction
|
||||||
if (westerly.length) passWind(westerly, 120 * modifier, 1, cellsX);
|
if (westerly.length) passWind(westerly, 120 * modifier, 1, cellsX);
|
||||||
if (easterly.length) passWind(easterly, 120 * modifier, -1, cellsX);
|
if (easterly.length) passWind(easterly, 120 * modifier, -1, cellsX);
|
||||||
|
|
@ -929,7 +929,7 @@ function generatePrecipitation() {
|
||||||
let humidity = maxPrec - cells.h[first]; // initial water amount
|
let humidity = maxPrec - cells.h[first]; // initial water amount
|
||||||
if (humidity <= 0) continue; // if first cell in row is too elevated cosdired wind dry
|
if (humidity <= 0) continue; // if first cell in row is too elevated cosdired wind dry
|
||||||
for (let s = 0, current = first; s < steps; s++, current += next) {
|
for (let s = 0, current = first; s < steps; s++, current += next) {
|
||||||
// no flux on permafrost
|
// no flux on permafrost
|
||||||
if (cells.temp[current] < -5) continue;
|
if (cells.temp[current] < -5) continue;
|
||||||
// water cell
|
// water cell
|
||||||
if (cells.h[current] < 20) {
|
if (cells.h[current] < 20) {
|
||||||
|
|
@ -1145,7 +1145,7 @@ function reMarkFeatures() {
|
||||||
cellNumber++;
|
cellNumber++;
|
||||||
}
|
}
|
||||||
if (land && !eLand) {
|
if (land && !eLand) {
|
||||||
cells.t[q] = 1;
|
cells.t[q] = 1;
|
||||||
cells.t[e] = -1;
|
cells.t[e] = -1;
|
||||||
cells.harbor[q]++;
|
cells.harbor[q]++;
|
||||||
if (!cells.haven[q]) cells.haven[q] = e;
|
if (!cells.haven[q]) cells.haven[q] = e;
|
||||||
|
|
@ -1259,7 +1259,7 @@ function addZone() {
|
||||||
|
|
||||||
const neib = state.neighbors.values().next().value;
|
const neib = state.neighbors.values().next().value;
|
||||||
const data = cells.i.filter(i => cells.state[i] === state.i && cells.c[i].some(c => cells.state[c] === neib));
|
const data = cells.i.filter(i => cells.state[i] === state.i && cells.c[i].some(c => cells.state[c] === neib));
|
||||||
|
|
||||||
const rebels = rw({Rebels:5, Insurgents:2, Recusants:1, Mutineers:1, Rioters:1, Dissenters:1, Secessionists:1, Insurrection:2, Rebellion:1, Conspiracy:2});
|
const rebels = rw({Rebels:5, Insurgents:2, Recusants:1, Mutineers:1, Rioters:1, Dissenters:1, Secessionists:1, Insurrection:2, Rebellion:1, Conspiracy:2});
|
||||||
const name = getAdjective(states[neib].name) + " " + rebels;
|
const name = getAdjective(states[neib].name) + " " + rebels;
|
||||||
|
|
||||||
|
|
@ -1317,7 +1317,7 @@ function addMarkers() {
|
||||||
void function addMines() {
|
void function addMines() {
|
||||||
let hills = Array.from(cells.i).filter(i => cells.h[i] > 47 && cells.burg[i]);
|
let hills = Array.from(cells.i).filter(i => cells.h[i] > 47 && cells.burg[i]);
|
||||||
let count = !hills.length ? 0 : Math.ceil(hills.length / 7);
|
let count = !hills.length ? 0 : Math.ceil(hills.length / 7);
|
||||||
if (!count) return;
|
if (!count) return;
|
||||||
|
|
||||||
addMarker("mine", "⚒", 50, 50, 20);
|
addMarker("mine", "⚒", 50, 50, 20);
|
||||||
const resources = {"salt":5, "gold":2, "silver":4, "copper":2, "iron":3, "lead":1, "tin":1};
|
const resources = {"salt":5, "gold":2, "silver":4, "copper":2, "iron":3, "lead":1, "tin":1};
|
||||||
|
|
@ -1373,11 +1373,11 @@ function addMarkers() {
|
||||||
let taverns = Array.from(cells.i).filter(i => cells.crossroad[i] && cells.h[i] >= 20 && cells.road[i] > maxRoad);
|
let taverns = Array.from(cells.i).filter(i => cells.crossroad[i] && cells.h[i] >= 20 && cells.road[i] > maxRoad);
|
||||||
if (!taverns.length) return;
|
if (!taverns.length) return;
|
||||||
addMarker("inn", "🍻", 50, 50, 17.5);
|
addMarker("inn", "🍻", 50, 50, 17.5);
|
||||||
|
|
||||||
const color = ["Dark", "Light", "Bright", "Golden", "White", "Black", "Red", "Pink", "Purple", "Blue", "Green", "Yellow", "Amber", "Orange", "Brown", "Grey"];
|
const color = ["Dark", "Light", "Bright", "Golden", "White", "Black", "Red", "Pink", "Purple", "Blue", "Green", "Yellow", "Amber", "Orange", "Brown", "Grey"];
|
||||||
const animal = ["Antelope", "Ape", "Badger", "Bear", "Beaver", "Bison", "Boar", "Buffalo", "Cat", "Crane", "Crocodile", "Crow", "Deer", "Dog", "Eagle", "Elk", "Fox", "Goat", "Goose", "Hare", "Hawk", "Heron", "Horse", "Hyena", "Ibis", "Jackal", "Jaguar", "Lark", "Leopard", "Lion", "Mantis", "Marten", "Moose", "Mule", "Narwhal", "Owl", "Panther", "Rat", "Raven", "Rook", "Scorpion", "Shark", "Sheep", "Snake", "Spider", "Swan", "Tiger", "Turtle", "Wolf", "Wolverine", "Camel", "Falcon", "Hound", "Ox"];
|
const animal = ["Antelope", "Ape", "Badger", "Bear", "Beaver", "Bison", "Boar", "Buffalo", "Cat", "Crane", "Crocodile", "Crow", "Deer", "Dog", "Eagle", "Elk", "Fox", "Goat", "Goose", "Hare", "Hawk", "Heron", "Horse", "Hyena", "Ibis", "Jackal", "Jaguar", "Lark", "Leopard", "Lion", "Mantis", "Marten", "Moose", "Mule", "Narwhal", "Owl", "Panther", "Rat", "Raven", "Rook", "Scorpion", "Shark", "Sheep", "Snake", "Spider", "Swan", "Tiger", "Turtle", "Wolf", "Wolverine", "Camel", "Falcon", "Hound", "Ox"];
|
||||||
const adj = ["New", "Good", "High", "Old", "Great", "Big", "Major", "Happy", "Main", "Huge", "Far", "Beautiful", "Fair", "Prime", "Ancient", "Golden", "Proud", "Lucky", "Fat", "Honest", "Giant", "Distant", "Friendly", "Loud", "Hungry", "Magical", "Superior", "Peaceful", "Frozen", "Divine", "Favorable", "Brave", "Sunny", "Flying"];
|
const adj = ["New", "Good", "High", "Old", "Great", "Big", "Major", "Happy", "Main", "Huge", "Far", "Beautiful", "Fair", "Prime", "Ancient", "Golden", "Proud", "Lucky", "Fat", "Honest", "Giant", "Distant", "Friendly", "Loud", "Hungry", "Magical", "Superior", "Peaceful", "Frozen", "Divine", "Favorable", "Brave", "Sunny", "Flying"];
|
||||||
|
|
||||||
|
|
||||||
for (let i=0; i < taverns.length && i < 4; i++) {
|
for (let i=0; i < taverns.length && i < 4; i++) {
|
||||||
const cell = taverns.splice(Math.floor(Math.random() * taverns.length), 1);
|
const cell = taverns.splice(Math.floor(Math.random() * taverns.length), 1);
|
||||||
|
|
|
||||||
11
maps/template_continent.txt
Normal file
11
maps/template_continent.txt
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
Hill 6-12 10-20 10-90 10-90
|
||||||
|
Hill 2-5 20-30 25-75 20-80
|
||||||
|
Smooth 1 0 0 0
|
||||||
|
Range 0-2 30-60 25-75 25-75
|
||||||
|
Smooth 2 0 0 0
|
||||||
|
Range 1-2 40-50 40-60 40-60
|
||||||
|
Multiply 1.2 land 0 0
|
||||||
|
Pit 1-3 10-30 30-70 20-80
|
||||||
|
Trough 0-2 20-30 15-85 20-80
|
||||||
|
Hill 2-4 10-25 15-85 20-80
|
||||||
|
Smooth 3 0 0 0
|
||||||
14
maps/template_squarish.txt
Normal file
14
maps/template_squarish.txt
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
Hill 2-3 10-25 20-30 20-30
|
||||||
|
Hill 1-2 10-25 20-30 70-80
|
||||||
|
Hill 2-3 10-25 70-80 20-30
|
||||||
|
Hill 1-2 10-25 70-80 70-80
|
||||||
|
Hill 6-12 10-20 30-70 30-70
|
||||||
|
Smooth 1 0 0 0
|
||||||
|
Hill 4-6 10-30 30-70 30-70
|
||||||
|
Range 1-2 40-50 20-80 20-40
|
||||||
|
Trough 1-2 10-30 15-85 40-80
|
||||||
|
Pit 2-4 10-20 15-85 20-80
|
||||||
|
Pit 1-2 20-30 25-75 60-80
|
||||||
|
Smooth 3 0 0 0
|
||||||
|
Range 0-2 40-50 15-85 20-80
|
||||||
|
Trough 0-2 40-50 15-85 20-80
|
||||||
13
maps/template_vertical.txt
Normal file
13
maps/template_vertical.txt
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
Hill 1 90-100 45-55 25-30
|
||||||
|
Hill 1 60-80 45-55 70-75
|
||||||
|
Hill 1 60-80 30-50 40-50
|
||||||
|
Hill 1 40-50 50-70 40-60
|
||||||
|
Multiply 0.6 20-100 0 0
|
||||||
|
Smooth 1 0 0 0
|
||||||
|
Range 0-2 40-50 30-60 30-60
|
||||||
|
Trough 1-3 20-40 25-75 20-80
|
||||||
|
Smooth 2 0 0 0
|
||||||
|
Pit 3-5 10-30 15-85 20-80
|
||||||
|
Hill 3-5 10-30 20-80 20-80
|
||||||
|
Range 1-2 20-50 30-70 20-65
|
||||||
|
Trough 1-2 20-50 15-85 20-80
|
||||||
|
|
@ -1,6 +1,176 @@
|
||||||
// Functions to save and load the map
|
// Functions to save and load the map
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
// download map data as GeoJSON
|
||||||
|
function saveGeoJSON() {
|
||||||
|
saveGeoJSON_Cells();
|
||||||
|
saveGeoJSON_Roads();
|
||||||
|
saveGeoJSON_Rivers();
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveGeoJSON_Roads() {
|
||||||
|
// this is work-in-progress
|
||||||
|
roads = routes.select("#roads");
|
||||||
|
trails = routes.select("#trails");
|
||||||
|
searoutes = routes.select("#searoutes");
|
||||||
|
|
||||||
|
let data = "{ \"type\": \"FeatureCollection\", \"features\": [\n";
|
||||||
|
|
||||||
|
routes._groups[0][0].childNodes.forEach(n => {
|
||||||
|
//console.log(n.id);
|
||||||
|
n.childNodes.forEach(r => {
|
||||||
|
data += "{\n \"type\": \"Feature\",\n \"geometry\": { \"type\": \"LineString\", \"coordinates\": ";
|
||||||
|
data += JSON.stringify(getRoadPoints(r));
|
||||||
|
data += " },\n \"properties\": {\n";
|
||||||
|
data += " \"id\": \""+r.id+"\",\n";
|
||||||
|
data += " \"type\": \""+n.id+"\"\n";
|
||||||
|
data +=" }\n},\n";
|
||||||
|
});
|
||||||
|
});
|
||||||
|
data = data.substring(0, data.length - 2)+"\n"; // remove trailing comma
|
||||||
|
data += "]}";
|
||||||
|
|
||||||
|
const dataBlob = new Blob([data], {type: "application/json"});
|
||||||
|
const url = window.URL.createObjectURL(dataBlob);
|
||||||
|
const link = document.createElement("a");
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.download = "fmg_routes_" + Date.now() + ".geojson";
|
||||||
|
link.href = url;
|
||||||
|
link.click();
|
||||||
|
window.setTimeout(function() {window.URL.revokeObjectURL(url);}, 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveGeoJSON_Rivers() {
|
||||||
|
let data = "{ \"type\": \"FeatureCollection\", \"features\": [\n";
|
||||||
|
|
||||||
|
rivers._groups[0][0].childNodes.forEach(n => {
|
||||||
|
data += "{\n \"type\": \"Feature\",\n \"geometry\": { \"type\": \"LineString\", \"coordinates\": ";
|
||||||
|
data += JSON.stringify(getRiverPoints(n));
|
||||||
|
data += " },\n \"properties\": {\n";
|
||||||
|
data += " \"id\": \""+n.id+"\",\n";
|
||||||
|
data += " \"width\": \""+n.dataset.width+"\",\n";
|
||||||
|
data += " \"increment\": \""+n.dataset.increment+"\"\n";
|
||||||
|
data +=" }\n},\n";
|
||||||
|
});
|
||||||
|
data = data.substring(0, data.length - 2)+"\n"; // remove trailing comma
|
||||||
|
data += "]}";
|
||||||
|
|
||||||
|
const dataBlob = new Blob([data], {type: "application/json"});
|
||||||
|
const url = window.URL.createObjectURL(dataBlob);
|
||||||
|
const link = document.createElement("a");
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.download = "fmg_rivers_" + Date.now() + ".geojson";
|
||||||
|
link.href = url;
|
||||||
|
link.click();
|
||||||
|
window.setTimeout(function() {window.URL.revokeObjectURL(url);}, 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRoadPoints(node) {
|
||||||
|
let points = [];
|
||||||
|
const l = node.getTotalLength();
|
||||||
|
const increment = l / Math.ceil(l / 2);
|
||||||
|
for (let i=0; i <= l; i += increment) {
|
||||||
|
const p = node.getPointAtLength(i);
|
||||||
|
|
||||||
|
let x = mapCoordinates.lonW + (p.x / graphWidth) * mapCoordinates.lonT;
|
||||||
|
let y = mapCoordinates.latN - (p.y / graphHeight) * mapCoordinates.latT; // this is inverted in QGIS otherwise
|
||||||
|
|
||||||
|
points.push([x,y]);
|
||||||
|
}
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRiverPoints(node) {
|
||||||
|
let points = [];
|
||||||
|
const l = node.getTotalLength() / 2; // half-length
|
||||||
|
const increment = 0.25; // defines density of points
|
||||||
|
for (let i=l, c=i; i >= 0; i -= increment, c += increment) {
|
||||||
|
const p1 = node.getPointAtLength(i);
|
||||||
|
const p2 = node.getPointAtLength(c);
|
||||||
|
|
||||||
|
let x = mapCoordinates.lonW + (((p1.x+p2.x)/2) / graphWidth) * mapCoordinates.lonT;
|
||||||
|
let y = mapCoordinates.latN - (((p1.y+p2.y)/2) / graphHeight) * mapCoordinates.latT; // this is inverted in QGIS otherwise
|
||||||
|
|
||||||
|
points.push([x,y]);
|
||||||
|
}
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function saveGeoJSON_Cells() {
|
||||||
|
let data = "{ \"type\": \"FeatureCollection\", \"features\": [\n";
|
||||||
|
|
||||||
|
const cells = pack.cells;
|
||||||
|
const v = pack.vertices;
|
||||||
|
|
||||||
|
/*
|
||||||
|
my guesses on the cells structure:
|
||||||
|
|
||||||
|
cells.h = height
|
||||||
|
cells.p = coordinates of center point (of the voronoi cell)
|
||||||
|
cells.pop = population
|
||||||
|
|
||||||
|
// from voronoi.js:
|
||||||
|
const cells = {v: [], c: [], b: []}; // voronoi cells: v = cell vertices, c = adjacent cells, b = near-border cell
|
||||||
|
const vertices = {p: [], v: [], c: []}; // cells vertices: p = vertex coordinates, v = neighboring vertices, c = adjacent cells
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
cells.i.forEach(i => {
|
||||||
|
data += "{\n \"type\": \"Feature\",\n \"geometry\": { \"type\": \"Polygon\", \"coordinates\": [[";
|
||||||
|
cells.v[i].forEach(n => {
|
||||||
|
let x = mapCoordinates.lonW + (v.p[n][0] / graphWidth) * mapCoordinates.lonT;
|
||||||
|
let y = mapCoordinates.latN - (v.p[n][1] / graphHeight) * mapCoordinates.latT; // this is inverted in QGIS otherwise
|
||||||
|
data += "["+x+","+y+"],";
|
||||||
|
});
|
||||||
|
// close the ring
|
||||||
|
let x = mapCoordinates.lonW + (v.p[cells.v[i][0]][0] / graphWidth) * mapCoordinates.lonT;
|
||||||
|
let y = mapCoordinates.latN - (v.p[cells.v[i][0]][1] / graphHeight) * mapCoordinates.latT; // this is inverted in QGIS otherwise
|
||||||
|
data += "["+x+","+y+"]";
|
||||||
|
|
||||||
|
data += "]] },\n \"properties\": {\n";
|
||||||
|
|
||||||
|
let height = parseInt(getFriendlyHeight(cells.h[i]));
|
||||||
|
|
||||||
|
data += " \"id\": \""+i+"\",\n";
|
||||||
|
data += " \"height\": \""+height+"\",\n";
|
||||||
|
data += " \"biome\": \""+cells.biome[i]+"\",\n";
|
||||||
|
data += " \"population\": \""+cells.pop[i]+"\",\n";
|
||||||
|
data += " \"state\": \""+cells.state[i]+"\",\n";
|
||||||
|
data += " \"province\": \""+cells.province[i]+"\",\n";
|
||||||
|
data += " \"culture\": \""+cells.culture[i]+"\",\n";
|
||||||
|
data += " \"religion\": \""+cells.religion[i]+"\"\n";
|
||||||
|
data +=" }\n},\n";
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
cells.i.forEach(i => {
|
||||||
|
let x = (cells.p[i][0] / graphWidth) * mapCoordinates.lonT + mapCoordinates.lonW;
|
||||||
|
let y = mapCoordinates.latN - (cells.p[i][1] / graphHeight) * mapCoordinates.lonT; // inverted in QGIS otherwise
|
||||||
|
let height = parseInt(getFriendlyHeight(cells.h[i]));
|
||||||
|
|
||||||
|
data += "{\n \"type\": \"Feature\",\n \"geometry\": { \"type\": \"Point\", \"coordinates\": ["+x+", "+y+", "+height+"] },\n \"properties\": {\n";
|
||||||
|
data += " \"id\": \""+i+"\",\n";
|
||||||
|
data += " \"biome\": \""+cells.biome[i]+"\",\n";
|
||||||
|
data += " \"height\": \""+cells.h[i]+"\"\n";
|
||||||
|
data +=" }\n},\n";
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
|
data = data.substring(0, data.length - 2)+"\n"; // remove trailing comma
|
||||||
|
data += "]}";
|
||||||
|
|
||||||
|
const dataBlob = new Blob([data], {type: "application/json"});
|
||||||
|
const url = window.URL.createObjectURL(dataBlob);
|
||||||
|
const link = document.createElement("a");
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.download = "fmg_cells_" + Date.now() + ".geojson";
|
||||||
|
link.href = url;
|
||||||
|
link.click();
|
||||||
|
window.setTimeout(function() {window.URL.revokeObjectURL(url);}, 2000);
|
||||||
|
}
|
||||||
|
|
||||||
// download map as SVG or PNG file
|
// download map as SVG or PNG file
|
||||||
function saveAsImage(type) {
|
function saveAsImage(type) {
|
||||||
console.time("saveAsImage");
|
console.time("saveAsImage");
|
||||||
|
|
@ -161,23 +331,23 @@ function getMapData() {
|
||||||
const dateString = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate();
|
const dateString = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate();
|
||||||
const license = "File can be loaded in azgaar.github.io/Fantasy-Map-Generator";
|
const license = "File can be loaded in azgaar.github.io/Fantasy-Map-Generator";
|
||||||
const params = [version, license, dateString, seed, graphWidth, graphHeight].join("|");
|
const params = [version, license, dateString, seed, graphWidth, graphHeight].join("|");
|
||||||
const options = [distanceUnitInput.value, distanceScaleInput.value, areaUnit.value, heightUnit.value, heightExponentInput.value, temperatureScale.value,
|
const options = [distanceUnitInput.value, distanceScaleInput.value, areaUnit.value, heightUnit.value, heightExponentInput.value, temperatureScale.value,
|
||||||
barSize.value, barLabel.value, barBackOpacity.value, barBackColor.value, barPosX.value, barPosY.value, populationRate.value, urbanization.value,
|
barSize.value, barLabel.value, barBackOpacity.value, barBackColor.value, barPosX.value, barPosY.value, populationRate.value, urbanization.value,
|
||||||
mapSizeOutput.value, latitudeOutput.value, temperatureEquatorOutput.value, temperaturePoleOutput.value, precOutput.value, JSON.stringify(winds)].join("|");
|
mapSizeOutput.value, latitudeOutput.value, temperatureEquatorOutput.value, temperaturePoleOutput.value, precOutput.value, JSON.stringify(winds)].join("|");
|
||||||
const coords = JSON.stringify(mapCoordinates);
|
const coords = JSON.stringify(mapCoordinates);
|
||||||
const biomes = [biomesData.color, biomesData.habitability, biomesData.name].join("|");
|
const biomes = [biomesData.color, biomesData.habitability, biomesData.name].join("|");
|
||||||
const notesData = JSON.stringify(notes);
|
const notesData = JSON.stringify(notes);
|
||||||
|
|
||||||
// set transform values to default
|
// set transform values to default
|
||||||
svg.attr("width", graphWidth).attr("height", graphHeight);
|
svg.attr("width", graphWidth).attr("height", graphHeight);
|
||||||
const transform = d3.zoomTransform(svg.node());
|
const transform = d3.zoomTransform(svg.node());
|
||||||
viewbox.attr("transform", null);
|
viewbox.attr("transform", null);
|
||||||
const svg_xml = (new XMLSerializer()).serializeToString(svg.node());
|
const svg_xml = (new XMLSerializer()).serializeToString(svg.node());
|
||||||
|
|
||||||
// restore initial values
|
// restore initial values
|
||||||
svg.attr("width", svgWidth).attr("height", svgHeight);
|
svg.attr("width", svgWidth).attr("height", svgHeight);
|
||||||
zoom.transform(svg, transform);
|
zoom.transform(svg, transform);
|
||||||
|
|
||||||
const gridGeneral = JSON.stringify({spacing:grid.spacing, cellsX:grid.cellsX, cellsY:grid.cellsY, boundary:grid.boundary, points:grid.points, features:grid.features});
|
const gridGeneral = JSON.stringify({spacing:grid.spacing, cellsX:grid.cellsX, cellsY:grid.cellsY, boundary:grid.boundary, points:grid.points, features:grid.features});
|
||||||
const features = JSON.stringify(pack.features);
|
const features = JSON.stringify(pack.features);
|
||||||
const cultures = JSON.stringify(pack.cultures);
|
const cultures = JSON.stringify(pack.cultures);
|
||||||
|
|
@ -185,13 +355,13 @@ function getMapData() {
|
||||||
const burgs = JSON.stringify(pack.burgs);
|
const burgs = JSON.stringify(pack.burgs);
|
||||||
const religions = JSON.stringify(pack.religions);
|
const religions = JSON.stringify(pack.religions);
|
||||||
const provinces = JSON.stringify(pack.provinces);
|
const provinces = JSON.stringify(pack.provinces);
|
||||||
|
|
||||||
// data format as below
|
// data format as below
|
||||||
const data = [params, options, coords, biomes, notesData, svg_xml,
|
const data = [params, options, coords, biomes, notesData, svg_xml,
|
||||||
gridGeneral, grid.cells.h, grid.cells.prec, grid.cells.f, grid.cells.t, grid.cells.temp,
|
gridGeneral, grid.cells.h, grid.cells.prec, grid.cells.f, grid.cells.t, grid.cells.temp,
|
||||||
features, cultures, states, burgs,
|
features, cultures, states, burgs,
|
||||||
pack.cells.biome, pack.cells.burg, pack.cells.conf, pack.cells.culture, pack.cells.fl,
|
pack.cells.biome, pack.cells.burg, pack.cells.conf, pack.cells.culture, pack.cells.fl,
|
||||||
pack.cells.pop, pack.cells.r, pack.cells.road, pack.cells.s, pack.cells.state,
|
pack.cells.pop, pack.cells.r, pack.cells.road, pack.cells.s, pack.cells.state,
|
||||||
pack.cells.religion, pack.cells.province, pack.cells.crossroad, religions, provinces].join("\r\n");
|
pack.cells.religion, pack.cells.province, pack.cells.crossroad, religions, provinces].join("\r\n");
|
||||||
const blob = new Blob([data], {type: "text/plain"});
|
const blob = new Blob([data], {type: "text/plain"});
|
||||||
|
|
||||||
|
|
@ -239,7 +409,7 @@ function uploadFile(file, callback) {
|
||||||
<br>Please keep using an ${archive}`;
|
<br>Please keep using an ${archive}`;
|
||||||
} else {
|
} else {
|
||||||
load = true;
|
load = true;
|
||||||
message = `The map version (${mapVersion}) does not match the Generator version (${version}).
|
message = `The map version (${mapVersion}) does not match the Generator version (${version}).
|
||||||
<br>The map will be auto-updated. In case of issues please keep using an ${archive} of the Generator`;
|
<br>The map will be auto-updated. In case of issues please keep using an ${archive} of the Generator`;
|
||||||
}
|
}
|
||||||
alertMessage.innerHTML = message;
|
alertMessage.innerHTML = message;
|
||||||
|
|
@ -256,16 +426,16 @@ function parseLoadedData(data) {
|
||||||
try {
|
try {
|
||||||
const reliefIcons = document.getElementById("defs-relief").innerHTML; // save relief icons
|
const reliefIcons = document.getElementById("defs-relief").innerHTML; // save relief icons
|
||||||
const hatching = document.getElementById("hatching").cloneNode(true); // save hatching
|
const hatching = document.getElementById("hatching").cloneNode(true); // save hatching
|
||||||
|
|
||||||
void function parseParameters() {
|
void function parseParameters() {
|
||||||
const params = data[0].split("|");
|
const params = data[0].split("|");
|
||||||
if (params[3]) {seed = params[3]; optionsSeed.value = seed;}
|
if (params[3]) {seed = params[3]; optionsSeed.value = seed;}
|
||||||
if (params[4]) graphWidth = +params[4];
|
if (params[4]) graphWidth = +params[4];
|
||||||
if (params[5]) graphHeight = +params[5];
|
if (params[5]) graphHeight = +params[5];
|
||||||
}()
|
}()
|
||||||
|
|
||||||
console.group("Loaded Map " + seed);
|
console.group("Loaded Map " + seed);
|
||||||
|
|
||||||
void function parseOptions() {
|
void function parseOptions() {
|
||||||
const options = data[1].split("|");
|
const options = data[1].split("|");
|
||||||
if (options[0]) applyOption(distanceUnitInput, options[0]);
|
if (options[0]) applyOption(distanceUnitInput, options[0]);
|
||||||
|
|
@ -289,17 +459,17 @@ function parseLoadedData(data) {
|
||||||
if (options[18]) precInput.value = precOutput.value = options[18];
|
if (options[18]) precInput.value = precOutput.value = options[18];
|
||||||
if (options[19]) winds = JSON.parse(options[19]);
|
if (options[19]) winds = JSON.parse(options[19]);
|
||||||
}()
|
}()
|
||||||
|
|
||||||
void function parseConfiguration() {
|
void function parseConfiguration() {
|
||||||
if (data[2]) mapCoordinates = JSON.parse(data[2]);
|
if (data[2]) mapCoordinates = JSON.parse(data[2]);
|
||||||
if (data[4]) notes = JSON.parse(data[4]);
|
if (data[4]) notes = JSON.parse(data[4]);
|
||||||
|
|
||||||
const biomes = data[3].split("|");
|
const biomes = data[3].split("|");
|
||||||
biomesData = applyDefaultBiomesSystem();
|
biomesData = applyDefaultBiomesSystem();
|
||||||
biomesData.color = biomes[0].split(",");
|
biomesData.color = biomes[0].split(",");
|
||||||
biomesData.habitability = biomes[1].split(",").map(h => +h);
|
biomesData.habitability = biomes[1].split(",").map(h => +h);
|
||||||
biomesData.name = biomes[2].split(",");
|
biomesData.name = biomes[2].split(",");
|
||||||
|
|
||||||
// push custom biomes if any
|
// push custom biomes if any
|
||||||
for (let i=biomesData.i.length; i < biomesData.name.length; i++) {
|
for (let i=biomesData.i.length; i < biomesData.name.length; i++) {
|
||||||
biomesData.i.push(biomesData.i.length);
|
biomesData.i.push(biomesData.i.length);
|
||||||
|
|
@ -308,12 +478,12 @@ function parseLoadedData(data) {
|
||||||
biomesData.cost.push(50);
|
biomesData.cost.push(50);
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
void function replaceSVG() {
|
void function replaceSVG() {
|
||||||
svg.remove();
|
svg.remove();
|
||||||
document.body.insertAdjacentHTML("afterbegin", data[5]);
|
document.body.insertAdjacentHTML("afterbegin", data[5]);
|
||||||
}()
|
}()
|
||||||
|
|
||||||
void function redefineElements() {
|
void function redefineElements() {
|
||||||
svg = d3.select("#map");
|
svg = d3.select("#map");
|
||||||
defs = svg.select("#deftemp");
|
defs = svg.select("#deftemp");
|
||||||
|
|
@ -364,7 +534,7 @@ function parseLoadedData(data) {
|
||||||
salt = lakes.select("#salt");
|
salt = lakes.select("#salt");
|
||||||
burgLabels = labels.select("#burgLabels");
|
burgLabels = labels.select("#burgLabels");
|
||||||
}()
|
}()
|
||||||
|
|
||||||
void function parseGridData() {
|
void function parseGridData() {
|
||||||
grid = JSON.parse(data[6]);
|
grid = JSON.parse(data[6]);
|
||||||
calculateVoronoi(grid, grid.points);
|
calculateVoronoi(grid, grid.points);
|
||||||
|
|
@ -374,7 +544,7 @@ function parseLoadedData(data) {
|
||||||
grid.cells.t = Int8Array.from(data[10].split(","));
|
grid.cells.t = Int8Array.from(data[10].split(","));
|
||||||
grid.cells.temp = Int8Array.from(data[11].split(","));
|
grid.cells.temp = Int8Array.from(data[11].split(","));
|
||||||
}()
|
}()
|
||||||
|
|
||||||
void function parsePackData() {
|
void function parsePackData() {
|
||||||
pack = {};
|
pack = {};
|
||||||
reGraph();
|
reGraph();
|
||||||
|
|
@ -385,7 +555,7 @@ function parseLoadedData(data) {
|
||||||
pack.burgs = JSON.parse(data[15]);
|
pack.burgs = JSON.parse(data[15]);
|
||||||
pack.religions = data[29] ? JSON.parse(data[29]) : [{i: 0, name: "No religion"}];
|
pack.religions = data[29] ? JSON.parse(data[29]) : [{i: 0, name: "No religion"}];
|
||||||
pack.provinces = data[30] ? JSON.parse(data[30]) : [0];
|
pack.provinces = data[30] ? JSON.parse(data[30]) : [0];
|
||||||
|
|
||||||
const cells = pack.cells;
|
const cells = pack.cells;
|
||||||
cells.biome = Uint8Array.from(data[16].split(","));
|
cells.biome = Uint8Array.from(data[16].split(","));
|
||||||
cells.burg = Uint16Array.from(data[17].split(","));
|
cells.burg = Uint16Array.from(data[17].split(","));
|
||||||
|
|
@ -401,7 +571,7 @@ function parseLoadedData(data) {
|
||||||
cells.province = data[27] ? Uint16Array.from(data[27].split(",")) : new Uint16Array(cells.i.length);
|
cells.province = data[27] ? Uint16Array.from(data[27].split(",")) : new Uint16Array(cells.i.length);
|
||||||
cells.crossroad = data[28] ? Uint16Array.from(data[28].split(",")) : new Uint16Array(cells.i.length);
|
cells.crossroad = data[28] ? Uint16Array.from(data[28].split(",")) : new Uint16Array(cells.i.length);
|
||||||
}()
|
}()
|
||||||
|
|
||||||
void function restoreLayersState() {
|
void function restoreLayersState() {
|
||||||
if (texture.style("display") !== "none" && texture.select("image").size()) turnButtonOn("toggleTexture"); else turnButtonOff("toggleTexture");
|
if (texture.style("display") !== "none" && texture.select("image").size()) turnButtonOn("toggleTexture"); else turnButtonOff("toggleTexture");
|
||||||
if (terrs.selectAll("*").size()) turnButtonOn("toggleHeight"); else turnButtonOff("toggleHeight");
|
if (terrs.selectAll("*").size()) turnButtonOn("toggleHeight"); else turnButtonOff("toggleHeight");
|
||||||
|
|
@ -426,15 +596,15 @@ function parseLoadedData(data) {
|
||||||
if (markers.selectAll("*").size() && markers.style("display") !== "none") turnButtonOn("toggleMarkers"); else turnButtonOff("toggleMarkers");
|
if (markers.selectAll("*").size() && markers.style("display") !== "none") turnButtonOn("toggleMarkers"); else turnButtonOff("toggleMarkers");
|
||||||
if (ruler.style("display") !== "none") turnButtonOn("toggleRulers"); else turnButtonOff("toggleRulers");
|
if (ruler.style("display") !== "none") turnButtonOn("toggleRulers"); else turnButtonOff("toggleRulers");
|
||||||
if (scaleBar.style("display") !== "none") turnButtonOn("toggleScaleBar"); else turnButtonOff("toggleScaleBar");
|
if (scaleBar.style("display") !== "none") turnButtonOn("toggleScaleBar"); else turnButtonOff("toggleScaleBar");
|
||||||
|
|
||||||
// special case for population bars
|
// special case for population bars
|
||||||
const populationIsOn = population.selectAll("line").size();
|
const populationIsOn = population.selectAll("line").size();
|
||||||
if (populationIsOn) drawPopulation();
|
if (populationIsOn) drawPopulation();
|
||||||
if (populationIsOn) turnButtonOn("togglePopulation"); else turnButtonOff("togglePopulation");
|
if (populationIsOn) turnButtonOn("togglePopulation"); else turnButtonOff("togglePopulation");
|
||||||
|
|
||||||
getCurrentPreset();
|
getCurrentPreset();
|
||||||
}()
|
}()
|
||||||
|
|
||||||
void function restoreEvents() {
|
void function restoreEvents() {
|
||||||
ruler.selectAll("g").call(d3.drag().on("start", dragRuler));
|
ruler.selectAll("g").call(d3.drag().on("start", dragRuler));
|
||||||
ruler.selectAll("text").on("click", removeParent);
|
ruler.selectAll("text").on("click", removeParent);
|
||||||
|
|
@ -443,36 +613,36 @@ function parseLoadedData(data) {
|
||||||
ruler.selectAll("g.ruler rect").call(d3.drag().on("start", rulerCenterDrag));
|
ruler.selectAll("g.ruler rect").call(d3.drag().on("start", rulerCenterDrag));
|
||||||
ruler.selectAll("g.opisometer circle").call(d3.drag().on("start", dragOpisometerEnd));
|
ruler.selectAll("g.opisometer circle").call(d3.drag().on("start", dragOpisometerEnd));
|
||||||
ruler.selectAll("g.opisometer circle").call(d3.drag().on("start", dragOpisometerEnd));
|
ruler.selectAll("g.opisometer circle").call(d3.drag().on("start", dragOpisometerEnd));
|
||||||
|
|
||||||
scaleBar.on("mousemove", () => tip("Click to open Units Editor"));
|
scaleBar.on("mousemove", () => tip("Click to open Units Editor"));
|
||||||
legend.on("mousemove", () => tip("Drag to change the position. Click to hide the legend")).on("click", () => clearLegend());
|
legend.on("mousemove", () => tip("Drag to change the position. Click to hide the legend")).on("click", () => clearLegend());
|
||||||
}()
|
}()
|
||||||
|
|
||||||
void function resolveVersionConflicts() {
|
void function resolveVersionConflicts() {
|
||||||
const version = parseFloat(data[0].split("|")[0]);
|
const version = parseFloat(data[0].split("|")[0]);
|
||||||
if (version == 0.8) {
|
if (version == 0.8) {
|
||||||
// 0.9 has additional relief icons to be included into older maps
|
// 0.9 has additional relief icons to be included into older maps
|
||||||
document.getElementById("defs-relief").innerHTML = reliefIcons;
|
document.getElementById("defs-relief").innerHTML = reliefIcons;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version < 1) {
|
if (version < 1) {
|
||||||
// 1.0 adds a new religions layer
|
// 1.0 adds a new religions layer
|
||||||
relig = viewbox.insert("g", "#terrain").attr("id", "relig");
|
relig = viewbox.insert("g", "#terrain").attr("id", "relig");
|
||||||
Religions.generate();
|
Religions.generate();
|
||||||
|
|
||||||
// 1.0 adds a legend box
|
// 1.0 adds a legend box
|
||||||
legend = svg.append("g").attr("id", "legend");
|
legend = svg.append("g").attr("id", "legend");
|
||||||
legend.attr("font-family", "Almendra SC").attr("data-font", "Almendra+SC")
|
legend.attr("font-family", "Almendra SC").attr("data-font", "Almendra+SC")
|
||||||
.attr("font-size", 13).attr("data-size", 13).attr("data-x", 99).attr("data-y", 93)
|
.attr("font-size", 13).attr("data-size", 13).attr("data-x", 99).attr("data-y", 93)
|
||||||
.attr("stroke-width", 2.5).attr("stroke", "#812929").attr("stroke-dasharray", "0 4 10 4").attr("stroke-linecap", "round");
|
.attr("stroke-width", 2.5).attr("stroke", "#812929").attr("stroke-dasharray", "0 4 10 4").attr("stroke-linecap", "round");
|
||||||
|
|
||||||
// 1.0 separated drawBorders fron drawStates()
|
// 1.0 separated drawBorders fron drawStates()
|
||||||
stateBorders = borders.append("g").attr("id", "stateBorders");
|
stateBorders = borders.append("g").attr("id", "stateBorders");
|
||||||
provinceBorders = borders.append("g").attr("id", "provinceBorders");
|
provinceBorders = borders.append("g").attr("id", "provinceBorders");
|
||||||
borders.attr("opacity", null).attr("stroke", null).attr("stroke-width", null).attr("stroke-dasharray", null).attr("stroke-linecap", null).attr("filter", null);
|
borders.attr("opacity", null).attr("stroke", null).attr("stroke-width", null).attr("stroke-dasharray", null).attr("stroke-linecap", null).attr("filter", null);
|
||||||
stateBorders.attr("opacity", .8).attr("stroke", "#56566d").attr("stroke-width", 1).attr("stroke-dasharray", "2").attr("stroke-linecap", "butt");
|
stateBorders.attr("opacity", .8).attr("stroke", "#56566d").attr("stroke-width", 1).attr("stroke-dasharray", "2").attr("stroke-linecap", "butt");
|
||||||
provinceBorders.attr("opacity", .8).attr("stroke", "#56566d").attr("stroke-width", .5).attr("stroke-dasharray", "1").attr("stroke-linecap", "butt");
|
provinceBorders.attr("opacity", .8).attr("stroke", "#56566d").attr("stroke-width", .5).attr("stroke-dasharray", "1").attr("stroke-linecap", "butt");
|
||||||
|
|
||||||
// 1.0 adds state relations, provinces, forms and full names
|
// 1.0 adds state relations, provinces, forms and full names
|
||||||
provs = viewbox.insert("g", "#borders").attr("id", "provs").attr("opacity", .6);
|
provs = viewbox.insert("g", "#borders").attr("id", "provs").attr("opacity", .6);
|
||||||
BurgsAndStates.collectStatistics();
|
BurgsAndStates.collectStatistics();
|
||||||
|
|
@ -483,57 +653,57 @@ function parseLoadedData(data) {
|
||||||
drawBorders();
|
drawBorders();
|
||||||
if (!layerIsOn("toggleBorders")) $('#borders').fadeOut();
|
if (!layerIsOn("toggleBorders")) $('#borders').fadeOut();
|
||||||
if (!layerIsOn("toggleStates")) regions.attr("display", "none").selectAll("path").remove();
|
if (!layerIsOn("toggleStates")) regions.attr("display", "none").selectAll("path").remove();
|
||||||
|
|
||||||
// 1.0 adds hatching
|
// 1.0 adds hatching
|
||||||
document.getElementsByTagName("defs")[0].appendChild(hatching);
|
document.getElementsByTagName("defs")[0].appendChild(hatching);
|
||||||
|
|
||||||
// 1.0 adds zones layer
|
// 1.0 adds zones layer
|
||||||
zones = viewbox.insert("g", "#borders").attr("id", "zones").attr("display", "none");
|
zones = viewbox.insert("g", "#borders").attr("id", "zones").attr("display", "none");
|
||||||
zones.attr("opacity", .6).attr("stroke", null).attr("stroke-width", 0).attr("stroke-dasharray", null).attr("stroke-linecap", "butt");
|
zones.attr("opacity", .6).attr("stroke", null).attr("stroke-width", 0).attr("stroke-dasharray", null).attr("stroke-linecap", "butt");
|
||||||
addZone();
|
addZone();
|
||||||
if (!markers.selectAll("*").size()) {addMarkers(); turnButtonOn("toggleMarkers");}
|
if (!markers.selectAll("*").size()) {addMarkers(); turnButtonOn("toggleMarkers");}
|
||||||
|
|
||||||
// 1.0 add fogging layer (state focus)
|
// 1.0 add fogging layer (state focus)
|
||||||
let fogging = viewbox.insert("g", "#ruler").attr("id", "fogging-cont").attr("mask", "url(#fog)")
|
let fogging = viewbox.insert("g", "#ruler").attr("id", "fogging-cont").attr("mask", "url(#fog)")
|
||||||
.append("g").attr("id", "fogging").attr("display", "none");
|
.append("g").attr("id", "fogging").attr("display", "none");
|
||||||
fogging.append("rect").attr("x", 0).attr("y", 0).attr("width", "100%").attr("height", "100%");
|
fogging.append("rect").attr("x", 0).attr("y", 0).attr("width", "100%").attr("height", "100%");
|
||||||
defs.append("mask").attr("id", "fog").append("rect").attr("x", 0).attr("y", 0).attr("width", "100%")
|
defs.append("mask").attr("id", "fog").append("rect").attr("x", 0).attr("y", 0).attr("width", "100%")
|
||||||
.attr("height", "100%").attr("fill", "white");
|
.attr("height", "100%").attr("fill", "white");
|
||||||
|
|
||||||
// 1.0 changes states opacity bask to regions level
|
// 1.0 changes states opacity bask to regions level
|
||||||
if (statesBody.attr("opacity")) {
|
if (statesBody.attr("opacity")) {
|
||||||
regions.attr("opacity", statesBody.attr("opacity"));
|
regions.attr("opacity", statesBody.attr("opacity"));
|
||||||
statesBody.attr("opacity", null);
|
statesBody.attr("opacity", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1.0 changed labels to multi-lined
|
// 1.0 changed labels to multi-lined
|
||||||
labels.selectAll("textPath").each(function() {
|
labels.selectAll("textPath").each(function() {
|
||||||
const text = this.textContent;
|
const text = this.textContent;
|
||||||
const shift = this.getComputedTextLength() / -1.5;
|
const shift = this.getComputedTextLength() / -1.5;
|
||||||
this.innerHTML = `<tspan x="${shift}">${text}</tspan>`;
|
this.innerHTML = `<tspan x="${shift}">${text}</tspan>`;
|
||||||
});
|
});
|
||||||
|
|
||||||
// 1.0 added new biome - Wetland
|
// 1.0 added new biome - Wetland
|
||||||
biomesData.name.push("Wetland");
|
biomesData.name.push("Wetland");
|
||||||
biomesData.color.push("#0b9131");
|
biomesData.color.push("#0b9131");
|
||||||
biomesData.habitability.push(12);
|
biomesData.habitability.push(12);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version == 1) {
|
if (version == 1) {
|
||||||
// v 1.0 initial code had a bug with religion layer id
|
// v 1.0 initial code had a bug with religion layer id
|
||||||
if (!relig.size()) relig = viewbox.insert("g", "#terrain").attr("id", "relig");
|
if (!relig.size()) relig = viewbox.insert("g", "#terrain").attr("id", "relig");
|
||||||
|
|
||||||
// v 1.0 initially has Sympathy status then relaced with Friendly
|
// v 1.0 initially has Sympathy status then relaced with Friendly
|
||||||
for (const s of pack.states) {
|
for (const s of pack.states) {
|
||||||
s.diplomacy = s.diplomacy.map(r => r === "Sympathy" ? "Friendly" : r);
|
s.diplomacy = s.diplomacy.map(r => r === "Sympathy" ? "Friendly" : r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
changeMapSize();
|
changeMapSize();
|
||||||
if (window.restoreDefaultEvents) restoreDefaultEvents();
|
if (window.restoreDefaultEvents) restoreDefaultEvents();
|
||||||
invokeActiveZooming();
|
invokeActiveZooming();
|
||||||
|
|
||||||
console.warn(`TOTAL: ${rn((performance.now()-uploadFile.timeStart)/1000,2)}s`);
|
console.warn(`TOTAL: ${rn((performance.now()-uploadFile.timeStart)/1000,2)}s`);
|
||||||
showStatistics();
|
showStatistics();
|
||||||
console.groupEnd("Loaded Map " + seed);
|
console.groupEnd("Loaded Map " + seed);
|
||||||
|
|
@ -635,4 +805,4 @@ function toggleSaveReminder() {
|
||||||
localStorage.removeItem("noReminder");
|
localStorage.removeItem("noReminder");
|
||||||
saveReminder();
|
saveReminder();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -252,7 +252,7 @@ function editBurgs() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function downloadBurgsData() {
|
function downloadBurgsData() {
|
||||||
let data = "Id,Burg,State,Culture,Population,Capital,Port\n"; // headers
|
let data = "Id,Burg,State,Culture,Population,Capital,Port,Longitude,Latitude,Elevation\n"; // headers
|
||||||
const valid = pack.burgs.filter(b => b.i && !b.removed); // all valid burgs
|
const valid = pack.burgs.filter(b => b.i && !b.removed); // all valid burgs
|
||||||
|
|
||||||
valid.forEach(b => {
|
valid.forEach(b => {
|
||||||
|
|
@ -262,7 +262,12 @@ function editBurgs() {
|
||||||
data += pack.cultures[b.culture].name + ",";
|
data += pack.cultures[b.culture].name + ",";
|
||||||
data += rn(b.population * populationRate.value * urbanization.value) + ",";
|
data += rn(b.population * populationRate.value * urbanization.value) + ",";
|
||||||
data += b.capital ? "capital," : ",";
|
data += b.capital ? "capital," : ",";
|
||||||
data += b.port ? "port\n" : "\n";
|
data += b.port ? "port," : ",";
|
||||||
|
|
||||||
|
// add geography data
|
||||||
|
data += mapCoordinates.lonW + (b.x / graphWidth) * mapCoordinates.lonT + ",";
|
||||||
|
data += mapCoordinates.latN - (b.y / graphHeight) * mapCoordinates.latT + ","; // this is inverted in QGIS otherwise
|
||||||
|
data += parseInt(getFriendlyHeight(pack.cells.h[b.cell])) + "\n";
|
||||||
});
|
});
|
||||||
|
|
||||||
const dataBlob = new Blob([data], {type: "text/plain"});
|
const dataBlob = new Blob([data], {type: "text/plain"});
|
||||||
|
|
@ -315,7 +320,7 @@ function editBurgs() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fileReader.readAsText(fileToLoad, "UTF-8");
|
fileReader.readAsText(fileToLoad, "UTF-8");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -339,4 +344,3 @@ function editBurgs() {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ function showOptions(event) {
|
||||||
regenerate.style.display = "none";
|
regenerate.style.display = "none";
|
||||||
options.style.display = "block";
|
options.style.display = "block";
|
||||||
optionsTrigger.style.display = "none";
|
optionsTrigger.style.display = "none";
|
||||||
|
|
||||||
if (event) event.stopPropagation();
|
if (event) event.stopPropagation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -49,19 +49,19 @@ collapsible.addEventListener("mouseleave", function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Activate options tab on click
|
// Activate options tab on click
|
||||||
options.querySelector("div.tab").addEventListener("click", function(event) {
|
options.querySelector("div.tab").addEventListener("click", function(event) {
|
||||||
if (event.target.tagName !== "BUTTON") return;
|
if (event.target.tagName !== "BUTTON") return;
|
||||||
const id = event.target.id;
|
const id = event.target.id;
|
||||||
const active = options.querySelector(".tab > button.active");
|
const active = options.querySelector(".tab > button.active");
|
||||||
if (active && id === active.id) return; // already active tab is clicked
|
if (active && id === active.id) return; // already active tab is clicked
|
||||||
|
|
||||||
if (active) active.classList.remove("active");
|
if (active) active.classList.remove("active");
|
||||||
document.getElementById(id).classList.add("active");
|
document.getElementById(id).classList.add("active");
|
||||||
options.querySelectorAll(".tabcontent").forEach(e => e.style.display = "none");
|
options.querySelectorAll(".tabcontent").forEach(e => e.style.display = "none");
|
||||||
|
|
||||||
if (id === "styleTab") styleContent.style.display = "block"; else
|
if (id === "styleTab") styleContent.style.display = "block"; else
|
||||||
if (id === "optionsTab") optionsContent.style.display = "block"; else
|
if (id === "optionsTab") optionsContent.style.display = "block"; else
|
||||||
if (id === "toolsTab" && (!customization || customization === 10)) toolsContent.style.display = "block"; else
|
if (id === "toolsTab" && (!customization || customization === 10)) toolsContent.style.display = "block"; else
|
||||||
if (id === "toolsTab" && customization && customization !== 10) customizationMenu.style.display = "block"; else
|
if (id === "toolsTab" && customization && customization !== 10) customizationMenu.style.display = "block"; else
|
||||||
if (id === "aboutTab") aboutContent.style.display = "block";
|
if (id === "aboutTab") aboutContent.style.display = "block";
|
||||||
});
|
});
|
||||||
|
|
@ -86,7 +86,7 @@ function selectStyleElement() {
|
||||||
const sel = styleElementSelect.value;
|
const sel = styleElementSelect.value;
|
||||||
let el = d3.select("#"+sel);
|
let el = d3.select("#"+sel);
|
||||||
|
|
||||||
styleElements.querySelectorAll("tbody").forEach(e => e.style.display = "none"); // hide all sections
|
styleElements.querySelectorAll("tbody").forEach(e => e.style.display = "none"); // hide all sections
|
||||||
const off = el.style("display") === "none" || !el.selectAll("*").size(); // check if layer is off
|
const off = el.style("display") === "none" || !el.selectAll("*").size(); // check if layer is off
|
||||||
if (off) {
|
if (off) {
|
||||||
styleIsOff.style.display = "block";
|
styleIsOff.style.display = "block";
|
||||||
|
|
@ -98,7 +98,7 @@ function selectStyleElement() {
|
||||||
if (sel == "ocean") el = oceanLayers.select("rect");
|
if (sel == "ocean") el = oceanLayers.select("rect");
|
||||||
else if (sel == "routes" || sel == "labels" || sel == "lakes" || sel == "anchors" || sel == "burgIcons" || sel == "borders") {
|
else if (sel == "routes" || sel == "labels" || sel == "lakes" || sel == "anchors" || sel == "burgIcons" || sel == "borders") {
|
||||||
el = d3.select("#"+sel).select("g#"+group).size()
|
el = d3.select("#"+sel).select("g#"+group).size()
|
||||||
? d3.select("#"+sel).select("g#"+group)
|
? d3.select("#"+sel).select("g#"+group)
|
||||||
: d3.select("#"+sel).select("g");
|
: d3.select("#"+sel).select("g");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -161,7 +161,7 @@ function selectStyleElement() {
|
||||||
styleCompassShiftY.value = tr[1];
|
styleCompassShiftY.value = tr[1];
|
||||||
styleCompassSizeInput.value = styleCompassSizeOutput.value = tr[2];
|
styleCompassSizeInput.value = styleCompassSizeOutput.value = tr[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
// show specific sections
|
// show specific sections
|
||||||
if (sel === "terrs") styleHeightmap.style.display = "block";
|
if (sel === "terrs") styleHeightmap.style.display = "block";
|
||||||
if (sel === "gridOverlay") styleGrid.style.display = "block";
|
if (sel === "gridOverlay") styleGrid.style.display = "block";
|
||||||
|
|
@ -169,7 +169,7 @@ function selectStyleElement() {
|
||||||
if (sel === "texture") styleTexture.style.display = "block";
|
if (sel === "texture") styleTexture.style.display = "block";
|
||||||
if (sel === "routes" || sel === "labels" || sel == "anchors" || sel == "burgIcons" || sel === "lakes" || sel === "borders") styleGroup.style.display = "block";
|
if (sel === "routes" || sel === "labels" || sel == "anchors" || sel == "burgIcons" || sel === "lakes" || sel === "borders") styleGroup.style.display = "block";
|
||||||
if (sel === "markers") styleMarkers.style.display = "block";
|
if (sel === "markers") styleMarkers.style.display = "block";
|
||||||
|
|
||||||
if (sel === "population") {
|
if (sel === "population") {
|
||||||
stylePopulation.style.display = "block";
|
stylePopulation.style.display = "block";
|
||||||
stylePopulationRuralStrokeInput.value = stylePopulationRuralStrokeOutput.value = population.select("#rural").attr("stroke");
|
stylePopulationRuralStrokeInput.value = stylePopulationRuralStrokeOutput.value = population.select("#rural").attr("stroke");
|
||||||
|
|
@ -256,7 +256,7 @@ function selectStyleElement() {
|
||||||
if (sel === "temperature") {
|
if (sel === "temperature") {
|
||||||
styleStrokeWidth.style.display = "block";
|
styleStrokeWidth.style.display = "block";
|
||||||
styleTemperature.style.display = "block";
|
styleTemperature.style.display = "block";
|
||||||
styleStrokeWidthInput.value = styleStrokeWidthOutput.value = el.attr("stroke-width") || "";
|
styleStrokeWidthInput.value = styleStrokeWidthOutput.value = el.attr("stroke-width") || "";
|
||||||
styleTemperatureFillOpacityInput.value = styleTemperatureFillOpacityOutput.value = el.attr("fill-opacity") || .1;
|
styleTemperatureFillOpacityInput.value = styleTemperatureFillOpacityOutput.value = el.attr("fill-opacity") || .1;
|
||||||
styleTemperatureFillInput.value = styleTemperatureFillOutput.value = el.attr("fill") || "#000";
|
styleTemperatureFillInput.value = styleTemperatureFillOutput.value = el.attr("fill") || "#000";
|
||||||
styleTemperatureFontSizeInput.value = styleTemperatureFontSizeOutput.value = el.attr("font-size") || "8px";;
|
styleTemperatureFontSizeInput.value = styleTemperatureFontSizeOutput.value = el.attr("font-size") || "8px";;
|
||||||
|
|
@ -363,7 +363,7 @@ styleShiftY.addEventListener("input", shiftElement);
|
||||||
function shiftElement() {
|
function shiftElement() {
|
||||||
const x = styleShiftX.value || 0;
|
const x = styleShiftX.value || 0;
|
||||||
const y = styleShiftY.value || 0;
|
const y = styleShiftY.value || 0;
|
||||||
getEl().attr("transform", `translate(${x},${y})`);
|
getEl().attr("transform", `translate(${x},${y})`);
|
||||||
}
|
}
|
||||||
|
|
||||||
styleOceanBack.addEventListener("input", function() {
|
styleOceanBack.addEventListener("input", function() {
|
||||||
|
|
@ -386,7 +386,7 @@ outlineLayersInput.addEventListener("change", function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
styleReliefSet.addEventListener("change", function() {
|
styleReliefSet.addEventListener("change", function() {
|
||||||
ReliefIcons();
|
ReliefIcons();
|
||||||
if (!layerIsOn("toggleRelief")) toggleRelief();
|
if (!layerIsOn("toggleRelief")) toggleRelief();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -447,7 +447,7 @@ styleCompassShiftY.addEventListener("input", shiftCompass);
|
||||||
|
|
||||||
function shiftCompass() {
|
function shiftCompass() {
|
||||||
const tr = `translate(${styleCompassShiftX.value} ${styleCompassShiftY.value}) scale(${styleCompassSizeInput.value})`;
|
const tr = `translate(${styleCompassShiftX.value} ${styleCompassShiftY.value}) scale(${styleCompassSizeInput.value})`;
|
||||||
d3.select("#rose").attr("transform", tr);
|
d3.select("#rose").attr("transform", tr);
|
||||||
}
|
}
|
||||||
|
|
||||||
styleLegendColItems.addEventListener("input", function() {
|
styleLegendColItems.addEventListener("input", function() {
|
||||||
|
|
@ -636,7 +636,7 @@ function setBase64Texture(url) {
|
||||||
};
|
};
|
||||||
|
|
||||||
function fetchTextureURL(url) {
|
function fetchTextureURL(url) {
|
||||||
console.log("Provided URL is", url);
|
console.log("Provided URL is", url);
|
||||||
const img = new Image();
|
const img = new Image();
|
||||||
img.onload = function () {
|
img.onload = function () {
|
||||||
const canvas = document.getElementById("preview");
|
const canvas = document.getElementById("preview");
|
||||||
|
|
@ -744,7 +744,7 @@ function toggleFullscreen() {
|
||||||
|
|
||||||
function generateMapWithSeed() {
|
function generateMapWithSeed() {
|
||||||
if (optionsSeed.value == seed) {
|
if (optionsSeed.value == seed) {
|
||||||
tip("The current map already has this seed", false, "error");
|
tip("The current map already has this seed", false, "error");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
regeneratePrompt();
|
regeneratePrompt();
|
||||||
|
|
@ -766,7 +766,7 @@ function showSeedHistoryDialog() {
|
||||||
// generate map with historycal seed
|
// generate map with historycal seed
|
||||||
function restoreSeed(id) {
|
function restoreSeed(id) {
|
||||||
if (mapHistory[id].seed == seed) {
|
if (mapHistory[id].seed == seed) {
|
||||||
tip("The current map is already generated with this seed", null, "error");
|
tip("The current map is already generated with this seed", null, "error");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
optionsSeed.value = mapHistory[id].seed;
|
optionsSeed.value = mapHistory[id].seed;
|
||||||
|
|
@ -803,7 +803,7 @@ function changeBurgsNumberSlider(value) {
|
||||||
function changeUIsize(value) {
|
function changeUIsize(value) {
|
||||||
uiSizeInput.value = uiSizeOutput.value = value;
|
uiSizeInput.value = uiSizeOutput.value = value;
|
||||||
document.getElementsByTagName("body")[0].style.fontSize = value * 11 + "px";
|
document.getElementsByTagName("body")[0].style.fontSize = value * 11 + "px";
|
||||||
document.getElementById("options").style.width = (value - 1) * 300 / 2 + 300 + "px";
|
document.getElementById("options").style.width = (value - 1) * 300 / 2 + 300 + "px";
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeTooltipSize(value) {
|
function changeTooltipSize(value) {
|
||||||
|
|
@ -992,8 +992,9 @@ document.getElementById("sticked").addEventListener("click", function(event) {
|
||||||
else if (id === "saveMap") saveMap();
|
else if (id === "saveMap") saveMap();
|
||||||
else if (id === "saveSVG") saveAsImage("svg");
|
else if (id === "saveSVG") saveAsImage("svg");
|
||||||
else if (id === "savePNG") saveAsImage("png");
|
else if (id === "savePNG") saveAsImage("png");
|
||||||
|
else if (id === "saveGeo") saveGeoJSON();
|
||||||
else if (id === "saveDropbox") saveDropbox();
|
else if (id === "saveDropbox") saveDropbox();
|
||||||
if (id === "quickSave" || id === "saveMap" || id === "saveSVG" || id === "savePNG" || id === "saveDropbox") toggleSavePane();
|
if (id === "quickSave" || id === "saveMap" || id === "saveSVG" || id === "savePNG" || id === "saveGeo" || id === "saveDropbox") toggleSavePane();
|
||||||
if (id === "loadMap") mapToLoad.click();
|
if (id === "loadMap") mapToLoad.click();
|
||||||
else if (id === "quickLoad") quickLoad();
|
else if (id === "quickLoad") quickLoad();
|
||||||
else if (id === "loadURL") loadURL();
|
else if (id === "loadURL") loadURL();
|
||||||
|
|
@ -1021,7 +1022,7 @@ function toggleSavePane() {
|
||||||
|
|
||||||
// ask users to allow popups
|
// ask users to allow popups
|
||||||
if (!localStorage.getItem("dns_allow_popup_message")) {
|
if (!localStorage.getItem("dns_allow_popup_message")) {
|
||||||
alertMessage.innerHTML = `Generator uses pop-up window to download files.
|
alertMessage.innerHTML = `Generator uses pop-up window to download files.
|
||||||
<br>Please ensure your browser does not block popups.
|
<br>Please ensure your browser does not block popups.
|
||||||
<br>Please check browser settings and turn off adBlocker if it is enabled`;
|
<br>Please check browser settings and turn off adBlocker if it is enabled`;
|
||||||
|
|
||||||
|
|
@ -1059,7 +1060,7 @@ function toggleLoadPane() {
|
||||||
|
|
||||||
function loadURL() {
|
function loadURL() {
|
||||||
const pattern = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
|
const pattern = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
|
||||||
const inner = `Provide URL to a .map file:
|
const inner = `Provide URL to a .map file:
|
||||||
<input id="mapURL" type="url" style="width: 254px" placeholder="https://e-cloud.com/test.map">
|
<input id="mapURL" type="url" style="width: 254px" placeholder="https://e-cloud.com/test.map">
|
||||||
<br><i>Please note server should allow CORS for file to be loaded. If CORS is not allowed, save file to Dropbox and provide a direct link</i>`;
|
<br><i>Please note server should allow CORS for file to be loaded. If CORS is not allowed, save file to Dropbox and provide a direct link</i>`;
|
||||||
alertMessage.innerHTML = inner;
|
alertMessage.innerHTML = inner;
|
||||||
|
|
@ -1103,4 +1104,4 @@ document.getElementById("mapToLoad").addEventListener("change", function() {
|
||||||
this.value = "";
|
this.value = "";
|
||||||
closeDialogs();
|
closeDialogs();
|
||||||
uploadFile(fileToLoad);
|
uploadFile(fileToLoad);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue