ci) {
+ if (ci.getReturnValue() == null || !(ci.getReturnValue().getTerrainType() instanceof EarthWorldType)) {
+ return;
+ }
+
+ Path settingsFile = EarthGeneratorSettings.settingsFile(this.worldDirectory.toPath());
+ if (Files.exists(settingsFile)) {
+ ((IWorldInfoAccess) ci.getReturnValue()).setGeneratorOptions(EarthGeneratorSettings.readSettings(settingsFile));
+ } else {
+ EarthGeneratorSettings.writeSettings(settingsFile, ci.getReturnValue().getGeneratorOptions());
+ }
+ }
+
+ @Inject(method = "Lnet/minecraft/world/storage/SaveHandler;saveWorldInfoWithPlayer(Lnet/minecraft/world/storage/WorldInfo;Lnet/minecraft/nbt/NBTTagCompound;)V",
+ at = @At("RETURN"),
+ require = 1)
+ private void terraplusplus_saveWorldInfoWithPlayer_writeSettingsToFile(WorldInfo worldInfo, NBTTagCompound nbt, CallbackInfo ci) {
+ if (!(worldInfo.getTerrainType() instanceof EarthWorldType)) {
+ return;
+ }
+
+ EarthGeneratorSettings.writeSettings(EarthGeneratorSettings.settingsFile(this.worldDirectory.toPath()), worldInfo.getGeneratorOptions());
+ }
+}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/asm/world/storage/MixinWorldInfo.java b/src/main/java/net/buildtheearth/terraplusplus/asm/world/storage/MixinWorldInfo.java
new file mode 100644
index 00000000..4d436352
--- /dev/null
+++ b/src/main/java/net/buildtheearth/terraplusplus/asm/world/storage/MixinWorldInfo.java
@@ -0,0 +1,33 @@
+package net.buildtheearth.terraplusplus.asm.world.storage;
+
+import net.buildtheearth.terraplusplus.EarthWorldType;
+import net.minecraft.world.WorldType;
+import net.minecraft.world.storage.WorldInfo;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Redirect;
+
+/**
+ * @author DaPorkchop_
+ */
+@Mixin(WorldInfo.class)
+public abstract class MixinWorldInfo {
+ @Shadow
+ private WorldType terrainType;
+
+ @Shadow
+ private String generatorOptions;
+
+ @Redirect(method = "Lnet/minecraft/world/storage/WorldInfo;updateTagCompound(Lnet/minecraft/nbt/NBTTagCompound;Lnet/minecraft/nbt/NBTTagCompound;)V",
+ at = @At(value = "FIELD",
+ target = "Lnet/minecraft/world/storage/WorldInfo;generatorOptions:Ljava/lang/String;"),
+ require = 1, allow = 1)
+ private String terraplusplus_updateTagCompound_dontStoreGeneratorOptionsToLevelDat(WorldInfo _this) {
+ if (this.terrainType instanceof EarthWorldType) {
+ return "";
+ } else {
+ return this.generatorOptions;
+ }
+ }
+}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/config/GlobalParseRegistries.java b/src/main/java/net/buildtheearth/terraplusplus/config/GlobalParseRegistries.java
index 432d9614..77e0b368 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/config/GlobalParseRegistries.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/config/GlobalParseRegistries.java
@@ -1,42 +1,83 @@
package net.buildtheearth.terraplusplus.config;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import com.fasterxml.jackson.databind.DatabindContext;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.jsontype.impl.TypeIdResolverBase;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.experimental.UtilityClass;
-import net.buildtheearth.terraplusplus.config.condition.AndDC;
-import net.buildtheearth.terraplusplus.config.condition.DoubleCondition;
-import net.buildtheearth.terraplusplus.config.condition.EqualDC;
-import net.buildtheearth.terraplusplus.config.condition.GreaterThanDC;
-import net.buildtheearth.terraplusplus.config.condition.LessThanDC;
-import net.buildtheearth.terraplusplus.config.condition.NotDC;
-import net.buildtheearth.terraplusplus.config.condition.OrDC;
-import net.buildtheearth.terraplusplus.config.scalarparse.d.AddDSP;
-import net.buildtheearth.terraplusplus.config.scalarparse.d.DivideDSP;
-import net.buildtheearth.terraplusplus.config.scalarparse.d.DoubleScalarParser;
-import net.buildtheearth.terraplusplus.config.scalarparse.d.FlipXDSP;
-import net.buildtheearth.terraplusplus.config.scalarparse.d.FlipZDSP;
-import net.buildtheearth.terraplusplus.config.scalarparse.d.FromIntDSP;
-import net.buildtheearth.terraplusplus.config.scalarparse.d.MultiplyDSP;
-import net.buildtheearth.terraplusplus.config.scalarparse.d.ParseFloatingPointTiffDSP;
-import net.buildtheearth.terraplusplus.config.scalarparse.d.ParseTerrariumPngDSP;
-import net.buildtheearth.terraplusplus.config.scalarparse.d.SwapAxesDSP;
-import net.buildtheearth.terraplusplus.config.scalarparse.i.AddISP;
-import net.buildtheearth.terraplusplus.config.scalarparse.i.AndISP;
-import net.buildtheearth.terraplusplus.config.scalarparse.i.FlipXISP;
-import net.buildtheearth.terraplusplus.config.scalarparse.i.FlipZISP;
-import net.buildtheearth.terraplusplus.config.scalarparse.i.GrayscaleExtractISP;
-import net.buildtheearth.terraplusplus.config.scalarparse.i.IntScalarParser;
-import net.buildtheearth.terraplusplus.config.scalarparse.i.ParseJpgISP;
-import net.buildtheearth.terraplusplus.config.scalarparse.i.ParsePngISP;
-import net.buildtheearth.terraplusplus.config.scalarparse.i.ParseTiffISP;
-import net.buildtheearth.terraplusplus.config.scalarparse.i.RGBExtractISP;
-import net.buildtheearth.terraplusplus.config.scalarparse.i.RequireOpaqueISP;
-import net.buildtheearth.terraplusplus.config.scalarparse.i.SwapAxesISP;
+import net.buildtheearth.terraplusplus.dataset.osm.dvalue.DValue;
+import net.buildtheearth.terraplusplus.dataset.osm.dvalue.DValueBinaryOperator;
+import net.buildtheearth.terraplusplus.dataset.osm.dvalue.DValueConstant;
+import net.buildtheearth.terraplusplus.dataset.osm.dvalue.DValueTag;
+import net.buildtheearth.terraplusplus.dataset.osm.mapper.line.LineMapper;
+import net.buildtheearth.terraplusplus.dataset.osm.mapper.line.LineMapperAll;
+import net.buildtheearth.terraplusplus.dataset.osm.mapper.line.LineMapperAny;
+import net.buildtheearth.terraplusplus.dataset.osm.mapper.line.LineMapperCondition;
+import net.buildtheearth.terraplusplus.dataset.osm.mapper.line.LineMapperFirst;
+import net.buildtheearth.terraplusplus.dataset.osm.mapper.line.LineMapperNarrow;
+import net.buildtheearth.terraplusplus.dataset.osm.mapper.line.LineMapperNothing;
+import net.buildtheearth.terraplusplus.dataset.osm.mapper.line.LineMapperWide;
+import net.buildtheearth.terraplusplus.dataset.osm.mapper.polygon.PolygonMapper;
+import net.buildtheearth.terraplusplus.dataset.osm.mapper.polygon.PolygonMapperAll;
+import net.buildtheearth.terraplusplus.dataset.osm.mapper.polygon.PolygonMapperAny;
+import net.buildtheearth.terraplusplus.dataset.osm.mapper.polygon.PolygonMapperCondition;
+import net.buildtheearth.terraplusplus.dataset.osm.mapper.polygon.PolygonMapperConvertToLines;
+import net.buildtheearth.terraplusplus.dataset.osm.mapper.polygon.PolygonMapperDistance;
+import net.buildtheearth.terraplusplus.dataset.osm.mapper.polygon.PolygonMapperFill;
+import net.buildtheearth.terraplusplus.dataset.osm.mapper.polygon.PolygonMapperFirst;
+import net.buildtheearth.terraplusplus.dataset.osm.mapper.polygon.PolygonMapperNothing;
+import net.buildtheearth.terraplusplus.dataset.osm.match.MatchCondition;
+import net.buildtheearth.terraplusplus.dataset.osm.match.MatchConditionAnd;
+import net.buildtheearth.terraplusplus.dataset.osm.match.MatchConditionId;
+import net.buildtheearth.terraplusplus.dataset.osm.match.MatchConditionIntersects;
+import net.buildtheearth.terraplusplus.dataset.osm.match.MatchConditionNot;
+import net.buildtheearth.terraplusplus.dataset.osm.match.MatchConditionOr;
+import net.buildtheearth.terraplusplus.dataset.osm.match.MatchConditionTag;
+import net.buildtheearth.terraplusplus.dataset.scalar.tile.format.TileFormat;
+import net.buildtheearth.terraplusplus.dataset.scalar.tile.format.TileFormatTerrariumPng;
+import net.buildtheearth.terraplusplus.dataset.scalar.tile.format.TileFormatTiff;
+import net.buildtheearth.terraplusplus.dataset.scalar.tile.mode.TileMode;
+import net.buildtheearth.terraplusplus.dataset.scalar.tile.mode.TileModeSimple;
+import net.buildtheearth.terraplusplus.dataset.scalar.tile.mode.TileModeSlippyMap;
+import net.buildtheearth.terraplusplus.dataset.vector.draw.DrawFunction;
+import net.buildtheearth.terraplusplus.dataset.vector.draw.DrawFunctionAll;
+import net.buildtheearth.terraplusplus.dataset.vector.draw.DrawFunctionBlock;
+import net.buildtheearth.terraplusplus.dataset.vector.draw.DrawFunctionConditionalRandom;
+import net.buildtheearth.terraplusplus.dataset.vector.draw.DrawFunctionNoTrees;
+import net.buildtheearth.terraplusplus.dataset.vector.draw.DrawFunctionOcean;
+import net.buildtheearth.terraplusplus.dataset.vector.draw.DrawFunctionWater;
+import net.buildtheearth.terraplusplus.dataset.vector.draw.DrawFunctionWeightAdd;
+import net.buildtheearth.terraplusplus.dataset.vector.draw.DrawFunctionWeightClamp;
+import net.buildtheearth.terraplusplus.dataset.vector.draw.DrawFunctionWeightGreaterThan;
+import net.buildtheearth.terraplusplus.dataset.vector.draw.DrawFunctionWeightLessThan;
+import net.buildtheearth.terraplusplus.generator.biome.BiomeFilterConstant;
+import net.buildtheearth.terraplusplus.generator.biome.BiomeFilterTerra121;
+import net.buildtheearth.terraplusplus.generator.biome.BiomeFilterUserOverride;
+import net.buildtheearth.terraplusplus.generator.biome.IEarthBiomeFilter;
+import net.buildtheearth.terraplusplus.generator.data.DataBakerHeights;
+import net.buildtheearth.terraplusplus.generator.data.DataBakerInitialBiomes;
+import net.buildtheearth.terraplusplus.generator.data.DataBakerNullIsland;
+import net.buildtheearth.terraplusplus.generator.data.DataBakerOSM;
+import net.buildtheearth.terraplusplus.generator.data.DataBakerTreeCover;
+import net.buildtheearth.terraplusplus.generator.data.IEarthDataBaker;
+import net.buildtheearth.terraplusplus.generator.populate.IEarthPopulator;
+import net.buildtheearth.terraplusplus.generator.populate.PopulatorBiomeDecoration;
+import net.buildtheearth.terraplusplus.generator.populate.PopulatorSnow;
+import net.buildtheearth.terraplusplus.generator.populate.PopulatorTrees;
+import net.buildtheearth.terraplusplus.generator.settings.osm.GeneratorOSMSettings;
+import net.buildtheearth.terraplusplus.generator.settings.osm.GeneratorOSMSettingsAll;
+import net.buildtheearth.terraplusplus.generator.settings.osm.GeneratorOSMSettingsCustom;
+import net.buildtheearth.terraplusplus.generator.settings.osm.GeneratorOSMSettingsDefault;
+import net.buildtheearth.terraplusplus.generator.settings.osm.GeneratorOSMSettingsDisable;
+import net.buildtheearth.terraplusplus.generator.settings.osm.GeneratorOSMSettingsToggle;
import net.buildtheearth.terraplusplus.projection.EqualEarthProjection;
import net.buildtheearth.terraplusplus.projection.EquirectangularProjection;
import net.buildtheearth.terraplusplus.projection.GeographicProjection;
+import net.buildtheearth.terraplusplus.projection.sis.SISProjectionWrapper;
import net.buildtheearth.terraplusplus.projection.SinusoidalProjection;
import net.buildtheearth.terraplusplus.projection.dymaxion.BTEDymaxionProjection;
import net.buildtheearth.terraplusplus.projection.dymaxion.ConformalDynmaxionProjection;
@@ -50,6 +91,10 @@
import net.buildtheearth.terraplusplus.projection.transform.ScaleProjectionTransform;
import net.buildtheearth.terraplusplus.projection.transform.SwapAxesProjectionTransform;
+import java.io.IOException;
+
+import static net.daporkchop.lib.common.util.PValidation.*;
+
/**
* Identifies implementation classes by their type names.
*
@@ -70,6 +115,7 @@ public class GlobalParseRegistries {
.put("bte_conformal_dymaxion", BTEDymaxionProjection.class)
.put("dymaxion", DymaxionProjection.class)
.put("conformal_dymaxion", ConformalDynmaxionProjection.class)
+ .put("wkt", SISProjectionWrapper.class)
//transformations
.put("flip_horizontal", FlipHorizontalProjectionTransform.class)
.put("flip_vertical", FlipVerticalProjectionTransform.class)
@@ -78,48 +124,112 @@ public class GlobalParseRegistries {
.put("swap_axes", SwapAxesProjectionTransform.class)
.build();
- public final BiMap> DOUBLE_CONDITIONS = new BiMapBuilder>()
- //conditions
- .put("equal", EqualDC.class)
- .put("greater_than", GreaterThanDC.class)
- .put("less_than", LessThanDC.class)
- //logical operators
- .put("and", AndDC.class)
- .put("not", NotDC.class)
- .put("or", OrDC.class)
+ public final BiMap> TILE_FORMATS = new BiMapBuilder>()
+ .put("terrarium_png", TileFormatTerrariumPng.class)
+ .put("tiff", TileFormatTiff.class)
+ .build();
+
+ public final BiMap> TILE_MODES = new BiMapBuilder>()
+ .put("simple", TileModeSimple.class)
+ .put("slippy", TileModeSlippyMap.class)
+ .build();
+
+ public final BiMap> OSM_LINE_MAPPERS = new BiMapBuilder>()
+ //mergers
+ .put("all", LineMapperAll.class)
+ .put("any", LineMapperAny.class)
+ .put("first", LineMapperFirst.class)
+ //misc.
+ .put("condition", LineMapperCondition.class)
+ .put("nothing", LineMapperNothing.class)
+ //emitters
+ .put("narrow", LineMapperNarrow.class)
+ .put("wide", LineMapperWide.class)
+ .build();
+
+ public final BiMap> OSM_POLYGON_MAPPERS = new BiMapBuilder>()
+ //mergers
+ .put("all", PolygonMapperAll.class)
+ .put("any", PolygonMapperAny.class)
+ .put("first", PolygonMapperFirst.class)
+ //misc.
+ .put("condition", PolygonMapperCondition.class)
+ .put("convert_to_lines", PolygonMapperConvertToLines.class)
+ .put("nothing", PolygonMapperNothing.class)
+ //emitters
+ .put("rasterize_distance", PolygonMapperDistance.class)
+ .put("rasterize_fill", PolygonMapperFill.class)
+ .build();
+
+ public final BiMap> OSM_DVALUES = new BiMapBuilder>()
+ //math operators
+ .put("+", DValueBinaryOperator.Add.class)
+ .put("-", DValueBinaryOperator.Subtract.class)
+ .put("*", DValueBinaryOperator.Multiply.class)
+ .put("/", DValueBinaryOperator.Divide.class)
+ .put("floor_div", DValueBinaryOperator.FloorDiv.class)
+ .put("min", DValueBinaryOperator.Min.class)
+ .put("max", DValueBinaryOperator.Max.class)
+ //misc.
+ .put("constant", DValueConstant.class)
+ .put("tag", DValueTag.class)
+ .build();
+
+ public final BiMap> OSM_MATCH_CONDITIONS = new BiMapBuilder>()
+ //logical operations
+ .put("and", MatchConditionAnd.class)
+ .put("not", MatchConditionNot.class)
+ .put("or", MatchConditionOr.class)
+ //misc.
+ .put("id", MatchConditionId.class)
+ .put("intersects", MatchConditionIntersects.class)
+ .put("tag", MatchConditionTag.class)
+ .build();
+
+ public final BiMap> VECTOR_DRAW_FUNCTIONS = new BiMapBuilder>()
+ //mergers
+ .put("all", DrawFunctionAll.class)
+ //conditional
+ .put("conditional_random", DrawFunctionConditionalRandom.class)
+ //weight modifiers
+ .put("weight_add", DrawFunctionWeightAdd.class)
+ .put("weight_clamp", DrawFunctionWeightClamp.class)
+ //weight conditions
+ .put("weight_greater_than", DrawFunctionWeightGreaterThan.class)
+ .put("weight_less_than", DrawFunctionWeightLessThan.class)
+ //misc.
+ .put("block", DrawFunctionBlock.class)
+ .put("no_trees", DrawFunctionNoTrees.class)
+ .put("ocean", DrawFunctionOcean.class)
+ .put("water", DrawFunctionWater.class)
+ .build();
+
+ public final BiMap> GENERATOR_SETTINGS_OSM = new BiMapBuilder>()
+ .put("all", GeneratorOSMSettingsAll.class)
+ .put("custom", GeneratorOSMSettingsCustom.class)
+ .put("default", GeneratorOSMSettingsDefault.class)
+ .put("disable", GeneratorOSMSettingsDisable.class)
+ .put("toggle", GeneratorOSMSettingsToggle.class)
+ .build();
+
+ public final BiMap> GENERATOR_SETTINGS_BIOME_FILTER = new BiMapBuilder>()
+ .put("constant", BiomeFilterConstant.class)
+ .put("legacy_terra121", BiomeFilterTerra121.class)
+ .put("user_overrides", BiomeFilterUserOverride.class)
.build();
- public final BiMap> SCALAR_PARSERS_DOUBLE = new BiMapBuilder>()
- //arithmetic operators
- .put("add", AddDSP.class)
- .put("divide", DivideDSP.class)
- .put("multiply", MultiplyDSP.class)
- //conversion operators
- .put("flip_x", FlipXDSP.class)
- .put("flip_z", FlipZDSP.class)
- .put("from_int", FromIntDSP.class)
- .put("swap_axes", SwapAxesDSP.class)
- //parse operators
- .put("parse_png_terrarium", ParseTerrariumPngDSP.class)
- .put("parse_tiff_fp", ParseFloatingPointTiffDSP.class)
+ public final BiMap> GENERATOR_SETTINGS_DATA_BAKER = new BiMapBuilder>()
+ .put("heights", DataBakerHeights.class)
+ .put("initial_biomes", DataBakerInitialBiomes.class)
+ .put("null_island", DataBakerNullIsland.class)
+ .put("osm", DataBakerOSM.class)
+ .put("tree_cover", DataBakerTreeCover.class)
.build();
- public final BiMap> SCALAR_PARSERS_INT = new BiMapBuilder>()
- //arithmetic operators
- .put("add", AddISP.class)
- //logical operators
- .put("and", AndISP.class)
- //conversion operators
- .put("flip_x", FlipXISP.class)
- .put("flip_z", FlipZISP.class)
- .put("grayscale_extract", GrayscaleExtractISP.class)
- .put("require_opaque", RequireOpaqueISP.class)
- .put("rgb_extract", RGBExtractISP.class)
- .put("swap_axes", SwapAxesISP.class)
- //parse operators
- .put("parse_jpg", ParseJpgISP.class)
- .put("parse_png", ParsePngISP.class)
- .put("parse_tiff", ParseTiffISP.class)
+ public final BiMap> GENERATOR_SETTINGS_POPULATOR = new BiMapBuilder>()
+ .put("biome_decorate", PopulatorBiomeDecoration.class)
+ .put("snow", PopulatorSnow.class)
+ .put("trees", PopulatorTrees.class)
.build();
/**
@@ -145,4 +255,37 @@ public BiMap build() {
return this.delegate;
}
}
+
+ /**
+ * Base implementation of a {@link com.fasterxml.jackson.databind.jsontype.TypeIdResolver} which uses a {@link BiMap}.
+ *
+ * @author DaPorkchop_
+ */
+ @RequiredArgsConstructor
+ public static abstract class TypeIdResolver extends TypeIdResolverBase {
+ @NonNull
+ protected final BiMap> registry;
+
+ @Override
+ public String idFromValue(Object value) {
+ return this.idFromValueAndType(value, value.getClass());
+ }
+
+ @Override
+ public String idFromValueAndType(Object value, Class> suggestedType) {
+ return this.registry.inverse().get(suggestedType);
+ }
+
+ @Override
+ public JavaType typeFromId(DatabindContext context, String id) throws IOException {
+ Class extends T> clazz = this.registry.get(id);
+ checkArg(clazz != null, "unknown id: %s", id);
+ return context.getConfig().getTypeFactory().constructType(clazz);
+ }
+
+ @Override
+ public JsonTypeInfo.Id getMechanism() {
+ return JsonTypeInfo.Id.CUSTOM;
+ }
+ }
}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/config/TypedDeserializer.java b/src/main/java/net/buildtheearth/terraplusplus/config/TypedDeserializer.java
index 38ba1290..f2cf616f 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/config/TypedDeserializer.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/config/TypedDeserializer.java
@@ -1,7 +1,6 @@
package net.buildtheearth.terraplusplus.config;
import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
diff --git a/src/main/java/net/buildtheearth/terraplusplus/config/TypedSerializer.java b/src/main/java/net/buildtheearth/terraplusplus/config/TypedSerializer.java
index aac4f264..bc764de5 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/config/TypedSerializer.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/config/TypedSerializer.java
@@ -5,7 +5,7 @@
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
-import net.buildtheearth.terraplusplus.TerraConstants;
+import net.buildtheearth.terraplusplus.util.TerraConstants;
import java.io.IOException;
import java.util.Map;
diff --git a/src/main/java/net/buildtheearth/terraplusplus/config/condition/AndDC.java b/src/main/java/net/buildtheearth/terraplusplus/config/condition/AndDC.java
deleted file mode 100644
index 7f3a9f37..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/config/condition/AndDC.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package net.buildtheearth.terraplusplus.config.condition;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonValue;
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import lombok.Getter;
-import lombok.NonNull;
-import lombok.RequiredArgsConstructor;
-import net.buildtheearth.terraplusplus.config.SingleProperty;
-
-/**
- * @author DaPorkchop_
- */
-@RequiredArgsConstructor(onConstructor_ = { @JsonCreator(mode = JsonCreator.Mode.DELEGATING) })
-@JsonDeserialize
-@Getter(onMethod_ = { @JsonValue })
-@SingleProperty
-public class AndDC implements DoubleCondition {
- @NonNull
- protected final DoubleCondition[] delegates;
-
- @Override
- public boolean test(double value) {
- for (DoubleCondition delegate : this.delegates) {
- if (!delegate.test(value)) {
- return false;
- }
- }
- return true;
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/config/condition/DoubleCondition.java b/src/main/java/net/buildtheearth/terraplusplus/config/condition/DoubleCondition.java
deleted file mode 100644
index a3ec208f..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/config/condition/DoubleCondition.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package net.buildtheearth.terraplusplus.config.condition;
-
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import com.fasterxml.jackson.databind.annotation.JsonSerialize;
-import net.buildtheearth.terraplusplus.config.GlobalParseRegistries;
-import net.buildtheearth.terraplusplus.config.TypedDeserializer;
-import net.buildtheearth.terraplusplus.config.TypedSerializer;
-
-import java.util.Map;
-import java.util.function.DoublePredicate;
-
-/**
- * A condition that accepts a {@code double} value and checks if it is applicable to a given argument.
- *
- * @author DaPorkchop_
- */
-@JsonDeserialize(using = DoubleCondition.Deserializer.class)
-@JsonSerialize(using = DoubleCondition.Serializer.class)
-@FunctionalInterface
-public interface DoubleCondition extends DoublePredicate {
- class Deserializer extends TypedDeserializer {
- @Override
- protected Map> registry() {
- return GlobalParseRegistries.DOUBLE_CONDITIONS;
- }
- }
-
- class Serializer extends TypedSerializer {
- @Override
- protected Map, String> registry() {
- return GlobalParseRegistries.DOUBLE_CONDITIONS.inverse();
- }
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/config/condition/GreaterThanDC.java b/src/main/java/net/buildtheearth/terraplusplus/config/condition/GreaterThanDC.java
deleted file mode 100644
index 5d295526..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/config/condition/GreaterThanDC.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package net.buildtheearth.terraplusplus.config.condition;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonValue;
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-import net.buildtheearth.terraplusplus.config.SingleProperty;
-
-/**
- * @author DaPorkchop_
- */
-@RequiredArgsConstructor(onConstructor_ = { @JsonCreator(mode = JsonCreator.Mode.DELEGATING) })
-@JsonDeserialize
-@Getter(onMethod_ = { @JsonValue })
-@SingleProperty
-public class GreaterThanDC implements DoubleCondition {
- protected final double value;
-
- @Override
- public boolean test(double value) {
- return value > this.value;
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/config/condition/LessThanDC.java b/src/main/java/net/buildtheearth/terraplusplus/config/condition/LessThanDC.java
deleted file mode 100644
index 1d6c6386..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/config/condition/LessThanDC.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package net.buildtheearth.terraplusplus.config.condition;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonValue;
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-import net.buildtheearth.terraplusplus.config.SingleProperty;
-
-/**
- * @author DaPorkchop_
- */
-@RequiredArgsConstructor(onConstructor_ = { @JsonCreator(mode = JsonCreator.Mode.DELEGATING) })
-@JsonDeserialize
-@Getter(onMethod_ = { @JsonValue })
-@SingleProperty
-public class LessThanDC implements DoubleCondition {
- protected final double value;
-
- @Override
- public boolean test(double value) {
- return value < this.value;
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/config/condition/OrDC.java b/src/main/java/net/buildtheearth/terraplusplus/config/condition/OrDC.java
deleted file mode 100644
index f7b67c93..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/config/condition/OrDC.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package net.buildtheearth.terraplusplus.config.condition;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonValue;
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import lombok.Getter;
-import lombok.NonNull;
-import lombok.RequiredArgsConstructor;
-import net.buildtheearth.terraplusplus.config.SingleProperty;
-
-/**
- * @author DaPorkchop_
- */
-@RequiredArgsConstructor(onConstructor_ = { @JsonCreator(mode = JsonCreator.Mode.DELEGATING) })
-@JsonDeserialize
-@Getter(onMethod_ = { @JsonValue })
-@SingleProperty
-public class OrDC implements DoubleCondition {
- @NonNull
- protected final DoubleCondition[] delegates;
-
- @Override
- public boolean test(double value) {
- for (DoubleCondition delegate : this.delegates) {
- if (delegate.test(value)) {
- return true;
- }
- }
- return false;
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/d/AddDSP.java b/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/d/AddDSP.java
deleted file mode 100644
index 904e863f..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/d/AddDSP.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package net.buildtheearth.terraplusplus.config.scalarparse.d;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonGetter;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import io.netty.buffer.ByteBuf;
-import lombok.Getter;
-import lombok.NonNull;
-
-import java.io.IOException;
-
-/**
- * @author DaPorkchop_
- */
-@JsonDeserialize
-@Getter(onMethod_ = { @JsonGetter })
-public class AddDSP implements DoubleScalarParser {
- protected final DoubleScalarParser delegate;
- protected final double value;
-
- @JsonCreator
- public AddDSP(
- @JsonProperty(value = "delegate", required = true) @NonNull DoubleScalarParser delegate,
- @JsonProperty(value = "value", required = true) double value) {
- this.delegate = delegate;
- this.value = value;
- }
-
- @Override
- public double[] parse(int resolution, @NonNull ByteBuf buffer) throws IOException {
- double[] arr = this.delegate.parse(resolution, buffer);
- double value = this.value;
- for (int i = 0, len = resolution * resolution; i < len; i++) {
- arr[i] += value;
- }
- return arr;
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/d/DivideDSP.java b/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/d/DivideDSP.java
deleted file mode 100644
index a14a391f..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/d/DivideDSP.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package net.buildtheearth.terraplusplus.config.scalarparse.d;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonGetter;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import io.netty.buffer.ByteBuf;
-import lombok.AccessLevel;
-import lombok.Getter;
-import lombok.NonNull;
-
-import java.io.IOException;
-
-/**
- * @author DaPorkchop_
- */
-@JsonDeserialize
-@Getter(onMethod_ = { @JsonGetter })
-public class DivideDSP implements DoubleScalarParser {
- protected final DoubleScalarParser delegate;
- protected final double value;
-
- @Getter(AccessLevel.NONE)
- protected final double factor;
-
- @JsonCreator
- public DivideDSP(
- @JsonProperty(value = "delegate", required = true) @NonNull DoubleScalarParser delegate,
- @JsonProperty(value = "value", required = true) double value) {
- this.delegate = delegate;
- this.value = value;
- this.factor = 1.0d / value;
- }
-
- @Override
- public double[] parse(int resolution, @NonNull ByteBuf buffer) throws IOException {
- double[] arr = this.delegate.parse(resolution, buffer);
- double factor = this.factor;
- for (int i = 0, len = resolution * resolution; i < len; i++) {
- arr[i] *= factor;
- }
- return arr;
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/d/DoubleScalarParser.java b/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/d/DoubleScalarParser.java
deleted file mode 100644
index 42d6a553..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/d/DoubleScalarParser.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package net.buildtheearth.terraplusplus.config.scalarparse.d;
-
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import com.fasterxml.jackson.databind.annotation.JsonSerialize;
-import io.netty.buffer.ByteBuf;
-import lombok.NonNull;
-import net.buildtheearth.terraplusplus.config.GlobalParseRegistries;
-import net.buildtheearth.terraplusplus.config.TypedDeserializer;
-import net.buildtheearth.terraplusplus.config.TypedSerializer;
-
-import java.io.IOException;
-import java.util.Map;
-
-/**
- * Parses a square grid of {@code double} values from a binary representation.
- *
- * @author DaPorkchop_
- */
-@JsonDeserialize(using = DoubleScalarParser.Deserializer.class)
-@JsonSerialize(using = DoubleScalarParser.Serializer.class)
-@FunctionalInterface
-public interface DoubleScalarParser {
- double[] parse(int resolution, @NonNull ByteBuf buffer) throws IOException;
-
- class Deserializer extends TypedDeserializer {
- @Override
- protected Map> registry() {
- return GlobalParseRegistries.SCALAR_PARSERS_DOUBLE;
- }
- }
-
- class Serializer extends TypedSerializer {
- @Override
- protected Map, String> registry() {
- return GlobalParseRegistries.SCALAR_PARSERS_DOUBLE.inverse();
- }
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/d/FlipXDSP.java b/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/d/FlipXDSP.java
deleted file mode 100644
index 9b1e366f..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/d/FlipXDSP.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package net.buildtheearth.terraplusplus.config.scalarparse.d;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonGetter;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import io.netty.buffer.ByteBuf;
-import lombok.Getter;
-import lombok.NonNull;
-
-import java.io.IOException;
-
-/**
- * @author DaPorkchop_
- */
-@JsonDeserialize
-@Getter(onMethod_ = { @JsonGetter })
-public class FlipXDSP implements DoubleScalarParser {
- protected final DoubleScalarParser delegate;
-
- @JsonCreator
- public FlipXDSP(@JsonProperty(value = "delegate", required = true) @NonNull DoubleScalarParser delegate) {
- this.delegate = delegate;
- }
-
- @Override
- public double[] parse(int resolution, @NonNull ByteBuf buffer) throws IOException {
- double[] arr = this.delegate.parse(resolution, buffer);
- for (int z = 0; z < resolution; z++) {
- for (int x = 0, lim = resolution >> 1; x < lim; x++) {
- int a = z * resolution + x;
- int b = z * resolution + (resolution - x - 1);
- double t = arr[a];
- arr[a] = arr[b];
- arr[b] = t;
- }
- }
- return arr;
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/d/FlipZDSP.java b/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/d/FlipZDSP.java
deleted file mode 100644
index df5b3ae1..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/d/FlipZDSP.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package net.buildtheearth.terraplusplus.config.scalarparse.d;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonGetter;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import io.netty.buffer.ByteBuf;
-import lombok.Getter;
-import lombok.NonNull;
-
-import java.io.IOException;
-
-/**
- * @author DaPorkchop_
- */
-@JsonDeserialize
-@Getter(onMethod_ = { @JsonGetter })
-public class FlipZDSP implements DoubleScalarParser {
- protected final DoubleScalarParser delegate;
-
- @JsonCreator
- public FlipZDSP(@JsonProperty(value = "delegate", required = true) @NonNull DoubleScalarParser delegate) {
- this.delegate = delegate;
- }
-
- @Override
- public double[] parse(int resolution, @NonNull ByteBuf buffer) throws IOException {
- double[] arr = this.delegate.parse(resolution, buffer);
- for (int z = 0, lim = resolution >> 1; z < lim; z++) {
- for (int x = 0; x < resolution; x++) {
- int a = z * resolution + x;
- int b = (resolution - z - 1) * resolution + x;
- double t = arr[a];
- arr[a] = arr[b];
- arr[b] = t;
- }
- }
- return arr;
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/d/FromIntDSP.java b/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/d/FromIntDSP.java
deleted file mode 100644
index 44bdb1d6..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/d/FromIntDSP.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package net.buildtheearth.terraplusplus.config.scalarparse.d;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonGetter;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import io.netty.buffer.ByteBuf;
-import lombok.Getter;
-import lombok.NonNull;
-import net.buildtheearth.terraplusplus.config.scalarparse.i.IntScalarParser;
-
-import java.io.IOException;
-
-/**
- * @author DaPorkchop_
- */
-@JsonDeserialize
-@Getter(onMethod_ = { @JsonGetter })
-public class FromIntDSP implements DoubleScalarParser {
- protected final IntScalarParser delegate;
-
- @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
- public FromIntDSP(@JsonProperty(value = "delegate", required = true) @NonNull IntScalarParser delegate) {
- this.delegate = delegate;
- }
-
- @Override
- public double[] parse(int resolution, @NonNull ByteBuf buffer) throws IOException {
- int[] src = this.delegate.parse(resolution, buffer);
- int len = resolution * resolution;
- double[] dst = new double[len];
- for (int i = 0; i < len; i++) {
- dst[i] = src[i] != Integer.MIN_VALUE ? src[i] : Double.NaN;
- }
- return dst;
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/d/MultiplyDSP.java b/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/d/MultiplyDSP.java
deleted file mode 100644
index fcf93c2a..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/d/MultiplyDSP.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package net.buildtheearth.terraplusplus.config.scalarparse.d;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonGetter;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import io.netty.buffer.ByteBuf;
-import lombok.Getter;
-import lombok.NonNull;
-
-import java.io.IOException;
-
-/**
- * @author DaPorkchop_
- */
-@JsonDeserialize
-@Getter(onMethod_ = { @JsonGetter })
-public class MultiplyDSP implements DoubleScalarParser {
- protected final DoubleScalarParser delegate;
- protected final double value;
-
- @JsonCreator
- public MultiplyDSP(
- @JsonProperty(value = "delegate", required = true) @NonNull DoubleScalarParser delegate,
- @JsonProperty(value = "value", required = true) double value) {
- this.delegate = delegate;
- this.value = value;
- }
-
- @Override
- public double[] parse(int resolution, @NonNull ByteBuf buffer) throws IOException {
- double[] arr = this.delegate.parse(resolution, buffer);
- double value = this.value;
- for (int i = 0, len = resolution * resolution; i < len; i++) {
- arr[i] *= value;
- }
- return arr;
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/d/ParseFloatingPointTiffDSP.java b/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/d/ParseFloatingPointTiffDSP.java
deleted file mode 100644
index 805bfd33..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/d/ParseFloatingPointTiffDSP.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package net.buildtheearth.terraplusplus.config.scalarparse.d;
-
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.ByteBufInputStream;
-import lombok.NonNull;
-import lombok.SneakyThrows;
-import org.apache.commons.imaging.FormatCompliance;
-import org.apache.commons.imaging.ImageReadException;
-import org.apache.commons.imaging.common.bytesource.ByteSourceInputStream;
-import org.apache.commons.imaging.formats.tiff.TiffContents;
-import org.apache.commons.imaging.formats.tiff.TiffDirectory;
-import org.apache.commons.imaging.formats.tiff.TiffField;
-import org.apache.commons.imaging.formats.tiff.TiffRasterData;
-import org.apache.commons.imaging.formats.tiff.TiffReader;
-import org.apache.commons.imaging.formats.tiff.constants.GdalLibraryTagConstants;
-
-import java.io.IOException;
-
-import static net.daporkchop.lib.common.util.PValidation.*;
-
-/**
- * @author DaPorkchop_
- */
-@JsonDeserialize
-public class ParseFloatingPointTiffDSP implements DoubleScalarParser {
- @Override
- @SneakyThrows(ImageReadException.class)
- public double[] parse(int resolution, @NonNull ByteBuf buffer) throws IOException {
- TiffContents contents = new TiffReader(false)
- .readDirectories(new ByteSourceInputStream(new ByteBufInputStream(buffer), ""), true, FormatCompliance.getDefault());
- TiffDirectory directory = contents.directories.get(0);
-
- TiffRasterData data = directory.getFloatingPointRasterData(null);
- int w = data.getWidth();
- int h = data.getHeight();
- checkArg(w == resolution && h == resolution, "invalid image resolution: %dx%d (expected: %dx%3$d)", w, h, resolution);
-
- TiffField nodataField = directory.findField(GdalLibraryTagConstants.EXIF_TAG_GDAL_NO_DATA);
- float nodata = nodataField != null ? Float.parseFloat(nodataField.getStringValue()) : Float.NaN;
-
- double[] out = new double[resolution * resolution];
- for (int i = 0; i < resolution * resolution; i++) {
- float f = data.getData()[i];
- out[i] = f == nodata ? Double.NaN : f;
- }
- return out;
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/d/ParseTerrariumPngDSP.java b/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/d/ParseTerrariumPngDSP.java
deleted file mode 100644
index 5c580f00..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/d/ParseTerrariumPngDSP.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package net.buildtheearth.terraplusplus.config.scalarparse.d;
-
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.ByteBufInputStream;
-import lombok.NonNull;
-import net.buildtheearth.terraplusplus.config.scalarparse.i.IntScalarParser;
-
-import javax.imageio.ImageIO;
-import java.awt.image.BufferedImage;
-import java.io.IOException;
-
-import static net.daporkchop.lib.common.util.PValidation.*;
-
-/**
- * @author DaPorkchop_
- */
-@JsonDeserialize
-public class ParseTerrariumPngDSP implements DoubleScalarParser {
- @Override
- public double[] parse(int resolution, @NonNull ByteBuf buffer) throws IOException {
- BufferedImage image = ImageIO.read(new ByteBufInputStream(buffer));
-
- int w = image.getWidth();
- int h = image.getHeight();
- checkArg(w == resolution && h == resolution, "invalid image resolution: %dx%d (expected: %dx%3$d)", w, h, resolution);
-
- int[] rgb = image.getRGB(0, 0, resolution, resolution, null, 0, resolution);
- double[] out = new double[resolution * resolution];
-
- for (int i = 0; i < resolution * resolution; i++) {
- int c = rgb[i];
- if ((c >>> 24) != 0xFF) { //nodata
- out[i] = Double.NaN;
- } else {
- out[i] = ((c & ~0xFF000000) - 0x00800000) * (1.0d / 256.0d);
- }
- }
-
- return out;
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/d/SwapAxesDSP.java b/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/d/SwapAxesDSP.java
deleted file mode 100644
index 8b71d2a7..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/d/SwapAxesDSP.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package net.buildtheearth.terraplusplus.config.scalarparse.d;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonGetter;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import io.netty.buffer.ByteBuf;
-import lombok.Getter;
-import lombok.NonNull;
-
-import java.io.IOException;
-
-/**
- * @author DaPorkchop_
- */
-@JsonDeserialize
-@Getter(onMethod_ = { @JsonGetter })
-public class SwapAxesDSP implements DoubleScalarParser {
- protected final DoubleScalarParser delegate;
-
- @JsonCreator
- public SwapAxesDSP(@JsonProperty(value = "delegate", required = true) @NonNull DoubleScalarParser delegate) {
- this.delegate = delegate;
- }
-
- @Override
- public double[] parse(int resolution, @NonNull ByteBuf buffer) throws IOException {
- double[] arr = this.delegate.parse(resolution, buffer);
- for (int i = 1; i < resolution; i++) {
- for (int j = 0; j < i; j++) {
- int a = i * resolution + j;
- int b = j * resolution + i;
- double t = arr[a];
- arr[a] = arr[b];
- arr[b] = t;
- }
- }
- return arr;
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/AddISP.java b/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/AddISP.java
deleted file mode 100644
index e5a4d62f..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/AddISP.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package net.buildtheearth.terraplusplus.config.scalarparse.i;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonGetter;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import io.netty.buffer.ByteBuf;
-import lombok.Getter;
-import lombok.NonNull;
-
-import java.io.IOException;
-
-/**
- * @author DaPorkchop_
- */
-@JsonDeserialize
-@Getter(onMethod_ = { @JsonGetter })
-public class AddISP implements IntScalarParser {
- protected final IntScalarParser delegate;
- protected final int value;
-
- @JsonCreator
- public AddISP(
- @JsonProperty(value = "delegate", required = true) @NonNull IntScalarParser delegate,
- @JsonProperty(value = "value", required = true) int value) {
- this.delegate = delegate;
- this.value = value;
- }
-
- @Override
- public int[] parse(int resolution, @NonNull ByteBuf buffer) throws IOException {
- int[] arr = this.delegate.parse(resolution, buffer);
- int value = this.value;
- for (int i = 0, len = resolution * resolution; i < len; i++) {
- arr[i] += value;
- }
- return arr;
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/AndISP.java b/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/AndISP.java
deleted file mode 100644
index 2c922aea..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/AndISP.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package net.buildtheearth.terraplusplus.config.scalarparse.i;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonGetter;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import io.netty.buffer.ByteBuf;
-import lombok.Getter;
-import lombok.NonNull;
-
-import java.io.IOException;
-
-/**
- * @author DaPorkchop_
- */
-@JsonDeserialize
-@Getter(onMethod_ = { @JsonGetter })
-public class AndISP implements IntScalarParser {
- protected final IntScalarParser delegate;
- protected final int mask;
-
- @JsonCreator
- public AndISP(
- @JsonProperty(value = "delegate", required = true) @NonNull IntScalarParser delegate,
- @JsonProperty(value = "mask", required = true) int mask) {
- this.delegate = delegate;
- this.mask = mask;
- }
-
- @Override
- public int[] parse(int resolution, @NonNull ByteBuf buffer) throws IOException {
- int[] arr = this.delegate.parse(resolution, buffer);
- int mask = this.mask;
- for (int i = 0, len = resolution * resolution; i < len; i++) {
- int v = arr[i];
- if (v != Integer.MIN_VALUE) {
- arr[i] = v & mask;
- }
- }
- return arr;
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/FlipXISP.java b/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/FlipXISP.java
deleted file mode 100644
index 45a023ec..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/FlipXISP.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package net.buildtheearth.terraplusplus.config.scalarparse.i;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonGetter;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import io.netty.buffer.ByteBuf;
-import lombok.Getter;
-import lombok.NonNull;
-
-import java.io.IOException;
-
-/**
- * @author DaPorkchop_
- */
-@JsonDeserialize
-@Getter(onMethod_ = { @JsonGetter })
-public class FlipXISP implements IntScalarParser {
- protected final IntScalarParser delegate;
-
- @JsonCreator
- public FlipXISP(@JsonProperty(value = "delegate", required = true) @NonNull IntScalarParser delegate) {
- this.delegate = delegate;
- }
-
- @Override
- public int[] parse(int resolution, @NonNull ByteBuf buffer) throws IOException {
- int[] arr = this.delegate.parse(resolution, buffer);
- for (int z = 0; z < resolution; z++) {
- for (int x = 0, lim = resolution >> 1; x < lim; x++) {
- int a = z * resolution + x;
- int b = z * resolution + (resolution - x - 1);
- int t = arr[a];
- arr[a] = arr[b];
- arr[b] = t;
- }
- }
- return arr;
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/FlipZISP.java b/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/FlipZISP.java
deleted file mode 100644
index 2b4b44ff..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/FlipZISP.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package net.buildtheearth.terraplusplus.config.scalarparse.i;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonGetter;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import io.netty.buffer.ByteBuf;
-import lombok.Getter;
-import lombok.NonNull;
-
-import java.io.IOException;
-
-/**
- * @author DaPorkchop_
- */
-@JsonDeserialize
-@Getter(onMethod_ = { @JsonGetter })
-public class FlipZISP implements IntScalarParser {
- protected final IntScalarParser delegate;
-
- @JsonCreator
- public FlipZISP(@JsonProperty(value = "delegate", required = true) @NonNull IntScalarParser delegate) {
- this.delegate = delegate;
- }
-
- @Override
- public int[] parse(int resolution, @NonNull ByteBuf buffer) throws IOException {
- int[] arr = this.delegate.parse(resolution, buffer);
- for (int z = 0, lim = resolution >> 1; z < lim; z++) {
- for (int x = 0; x < resolution; x++) {
- int a = z * resolution + x;
- int b = (resolution - z - 1) * resolution + x;
- int t = arr[a];
- arr[a] = arr[b];
- arr[b] = t;
- }
- }
- return arr;
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/GrayscaleExtractISP.java b/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/GrayscaleExtractISP.java
deleted file mode 100644
index 0c05090d..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/GrayscaleExtractISP.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package net.buildtheearth.terraplusplus.config.scalarparse.i;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonGetter;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import io.netty.buffer.ByteBuf;
-import lombok.Getter;
-import lombok.NonNull;
-
-import java.io.IOException;
-
-/**
- * @author DaPorkchop_
- */
-@JsonDeserialize
-@Getter(onMethod_ = { @JsonGetter })
-public class GrayscaleExtractISP implements IntScalarParser {
- protected final IntScalarParser delegate;
-
- @JsonCreator
- public GrayscaleExtractISP(@JsonProperty(value = "delegate", required = true) @NonNull IntScalarParser delegate) {
- this.delegate = delegate;
- }
-
- @Override
- public int[] parse(int resolution, @NonNull ByteBuf buffer) throws IOException {
- int[] arr = this.delegate.parse(resolution, buffer);
- for (int i = 0, len = resolution * resolution; i < len; i++) {
- int val = arr[i];
- arr[i] = (val >>> 24) == 0xFF ? arr[i] & 0x000000FF : Integer.MIN_VALUE;
- }
- return arr;
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/IntScalarParser.java b/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/IntScalarParser.java
deleted file mode 100644
index 5eded411..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/IntScalarParser.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package net.buildtheearth.terraplusplus.config.scalarparse.i;
-
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import com.fasterxml.jackson.databind.annotation.JsonSerialize;
-import io.netty.buffer.ByteBuf;
-import lombok.NonNull;
-import net.buildtheearth.terraplusplus.config.GlobalParseRegistries;
-import net.buildtheearth.terraplusplus.config.TypedDeserializer;
-import net.buildtheearth.terraplusplus.config.TypedSerializer;
-
-import java.io.IOException;
-import java.util.Map;
-
-/**
- * Parses a square grid of {@code int} values from a binary representation.
- *
- * @author DaPorkchop_
- */
-@JsonDeserialize(using = IntScalarParser.Deserializer.class)
-@JsonSerialize(using = IntScalarParser.Serializer.class)
-@FunctionalInterface
-public interface IntScalarParser {
- int[] parse(int resolution, @NonNull ByteBuf buffer) throws IOException;
-
- class Deserializer extends TypedDeserializer {
- @Override
- protected Map> registry() {
- return GlobalParseRegistries.SCALAR_PARSERS_INT;
- }
- }
-
- class Serializer extends TypedSerializer {
- @Override
- protected Map, String> registry() {
- return GlobalParseRegistries.SCALAR_PARSERS_INT.inverse();
- }
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/ParseJpgISP.java b/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/ParseJpgISP.java
deleted file mode 100644
index 75b163b3..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/ParseJpgISP.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package net.buildtheearth.terraplusplus.config.scalarparse.i;
-
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-
-/**
- * @author DaPorkchop_
- */
-@JsonDeserialize
-public class ParseJpgISP extends ParsePngISP {
- //we don't actually need to do anything different, since ImageIO does automatic type detection...
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/ParsePngISP.java b/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/ParsePngISP.java
deleted file mode 100644
index c9a79b42..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/ParsePngISP.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package net.buildtheearth.terraplusplus.config.scalarparse.i;
-
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.ByteBufInputStream;
-import lombok.NonNull;
-
-import javax.imageio.ImageIO;
-import java.awt.image.BufferedImage;
-import java.io.IOException;
-
-import static net.daporkchop.lib.common.util.PValidation.*;
-
-/**
- * @author DaPorkchop_
- */
-@JsonDeserialize
-public class ParsePngISP implements IntScalarParser {
- @Override
- public int[] parse(int resolution, @NonNull ByteBuf buffer) throws IOException {
- BufferedImage image = ImageIO.read(new ByteBufInputStream(buffer));
-
- int w = image.getWidth();
- int h = image.getHeight();
- checkArg(w == resolution && h == resolution, "invalid image resolution: %dx%d (expected: %dx%3$d)", w, h, resolution);
-
- return image.getRGB(0, 0, resolution, resolution, null, 0, resolution);
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/ParseTiffISP.java b/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/ParseTiffISP.java
deleted file mode 100644
index 44f88101..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/ParseTiffISP.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package net.buildtheearth.terraplusplus.config.scalarparse.i;
-
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.ByteBufInputStream;
-import lombok.NonNull;
-import lombok.SneakyThrows;
-import org.apache.commons.imaging.ImageReadException;
-import org.apache.commons.imaging.common.bytesource.ByteSourceInputStream;
-import org.apache.commons.imaging.formats.tiff.TiffImageParser;
-
-import java.awt.image.BufferedImage;
-import java.io.IOException;
-import java.util.Collections;
-
-import static net.daporkchop.lib.common.util.PValidation.*;
-
-/**
- * @author DaPorkchop_
- */
-@JsonDeserialize
-public class ParseTiffISP implements IntScalarParser {
- @Override
- @SneakyThrows(ImageReadException.class)
- public int[] parse(int resolution, @NonNull ByteBuf buffer) throws IOException {
- BufferedImage image = new TiffImageParser().getBufferedImage(new ByteSourceInputStream(new ByteBufInputStream(buffer), ""), Collections.emptyMap());
-
- int w = image.getWidth();
- int h = image.getHeight();
- checkArg(w == resolution && h == resolution, "invalid image resolution: %dx%d (expected: %dx%3$d)", w, h, resolution);
-
- return image.getRGB(0, 0, resolution, resolution, null, 0, resolution);
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/RGBExtractISP.java b/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/RGBExtractISP.java
deleted file mode 100644
index 1fa843b5..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/RGBExtractISP.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package net.buildtheearth.terraplusplus.config.scalarparse.i;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonGetter;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import io.netty.buffer.ByteBuf;
-import lombok.Getter;
-import lombok.NonNull;
-
-import java.io.IOException;
-
-/**
- * @author DaPorkchop_
- */
-@JsonDeserialize
-@Getter(onMethod_ = { @JsonGetter })
-public class RGBExtractISP implements IntScalarParser {
- protected final IntScalarParser delegate;
-
- @JsonCreator
- public RGBExtractISP(@JsonProperty(value = "delegate", required = true) @NonNull IntScalarParser delegate) {
- this.delegate = delegate;
- }
-
- @Override
- public int[] parse(int resolution, @NonNull ByteBuf buffer) throws IOException {
- int[] arr = this.delegate.parse(resolution, buffer);
- for (int i = 0, len = resolution * resolution; i < len; i++) {
- int val = arr[i];
- arr[i] = (val >>> 24) == 0xFF ? arr[i] & 0x00FFFFFF : Integer.MIN_VALUE;
- }
- return arr;
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/RequireOpaqueISP.java b/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/RequireOpaqueISP.java
deleted file mode 100644
index 8e1b420e..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/RequireOpaqueISP.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package net.buildtheearth.terraplusplus.config.scalarparse.i;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonGetter;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import io.netty.buffer.ByteBuf;
-import lombok.Getter;
-import lombok.NonNull;
-
-import java.io.IOException;
-
-/**
- * @author DaPorkchop_
- */
-@JsonDeserialize
-@Getter(onMethod_ = { @JsonGetter })
-public class RequireOpaqueISP implements IntScalarParser {
- protected final IntScalarParser delegate;
-
- @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
- public RequireOpaqueISP(@JsonProperty(value = "delegate", required = true) @NonNull IntScalarParser delegate) {
- this.delegate = delegate;
- }
-
- @Override
- public int[] parse(int resolution, @NonNull ByteBuf buffer) throws IOException {
- int[] arr = this.delegate.parse(resolution, buffer);
- for (int i = 0, len = resolution * resolution; i < len; i++) {
- if ((arr[i] >>> 24) != 0xFF) { //pixel is not fully transparent
- arr[i] = Integer.MIN_VALUE;
- }
- }
- return arr;
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/SwapAxesISP.java b/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/SwapAxesISP.java
deleted file mode 100644
index 171a5164..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/config/scalarparse/i/SwapAxesISP.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package net.buildtheearth.terraplusplus.config.scalarparse.i;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonGetter;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-import io.netty.buffer.ByteBuf;
-import lombok.Getter;
-import lombok.NonNull;
-
-import java.io.IOException;
-
-/**
- * @author DaPorkchop_
- */
-@JsonDeserialize
-@Getter(onMethod_ = { @JsonGetter })
-public class SwapAxesISP implements IntScalarParser {
- protected final IntScalarParser delegate;
-
- @JsonCreator
- public SwapAxesISP(@JsonProperty(value = "delegate", required = true) @NonNull IntScalarParser delegate) {
- this.delegate = delegate;
- }
-
- @Override
- public int[] parse(int resolution, @NonNull ByteBuf buffer) throws IOException {
- int[] arr = this.delegate.parse(resolution, buffer);
- for (int i = 1; i < resolution; i++) {
- for (int j = 0; j < i; j++) {
- int a = i * resolution + j;
- int b = j * resolution + i;
- int t = arr[a];
- arr[a] = arr[b];
- arr[b] = t;
- }
- }
- return arr;
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/control/AdvancedEarthGui.java b/src/main/java/net/buildtheearth/terraplusplus/control/AdvancedEarthGui.java
index d47fec8f..570b9215 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/control/AdvancedEarthGui.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/control/AdvancedEarthGui.java
@@ -1,20 +1,27 @@
package net.buildtheearth.terraplusplus.control;
+import com.fasterxml.jackson.core.JsonProcessingException;
import io.github.opencubicchunks.cubicchunks.cubicgen.customcubic.CustomCubicWorldType;
import lombok.Getter;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
-import net.buildtheearth.terraplusplus.TerraConstants;
+import lombok.SneakyThrows;
import net.buildtheearth.terraplusplus.TerraMod;
import net.buildtheearth.terraplusplus.config.GlobalParseRegistries;
import net.buildtheearth.terraplusplus.generator.EarthGeneratorSettings;
import net.buildtheearth.terraplusplus.projection.GeographicProjection;
+import net.buildtheearth.terraplusplus.projection.GeographicProjectionHelper;
import net.buildtheearth.terraplusplus.projection.OutOfProjectionBoundsException;
import net.buildtheearth.terraplusplus.projection.transform.OffsetProjectionTransform;
import net.buildtheearth.terraplusplus.projection.transform.ProjectionTransform;
import net.buildtheearth.terraplusplus.projection.transform.ScaleProjectionTransform;
+import net.buildtheearth.terraplusplus.util.CornerBoundingBox2d;
+import net.buildtheearth.terraplusplus.util.TerraConstants;
+import net.buildtheearth.terraplusplus.util.compat.sis.SISHelper;
+import net.buildtheearth.terraplusplus.util.math.matrix.TMatrices;
import net.daporkchop.lib.common.function.io.IOSupplier;
-import net.daporkchop.lib.common.ref.Ref;
+import net.daporkchop.lib.common.reference.ReferenceStrength;
+import net.daporkchop.lib.common.reference.cache.Cached;
import net.daporkchop.lib.common.util.PArrays;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
@@ -24,25 +31,38 @@
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.GuiTextField;
import net.minecraft.client.gui.ScaledResolution;
+import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.texture.DynamicTexture;
+import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.WorldType;
import net.minecraftforge.client.event.GuiOpenEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.terraingen.DecorateBiomeEvent;
import net.minecraftforge.event.terraingen.PopulateChunkEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import org.apache.sis.geometry.DirectPosition2D;
+import org.apache.sis.parameter.DefaultParameterDescriptorGroup;
+import org.apache.sis.parameter.DefaultParameterValueGroup;
+import org.apache.sis.referencing.operation.matrix.Matrix2;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
+import org.opengis.parameter.GeneralParameterDescriptor;
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.TransformException;
import javax.imageio.ImageIO;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -70,13 +90,17 @@
public class AdvancedEarthGui extends GuiScreen {
protected static final int SRC_W = 2048;
protected static final int SRC_H = 1024;
- protected static final Ref SRC_CACHE = Ref.soft((IOSupplier) () ->
- ImageIO.read(AdvancedEarthGui.class.getResource("map.png")).getRGB(0, 0, SRC_W, SRC_H, null, 0, SRC_W));
+ protected static final Cached SRC_CACHE = Cached.threadLocal((IOSupplier) () ->
+ ImageIO.read(AdvancedEarthGui.class.getResource("map.png")).getRGB(0, 0, SRC_W, SRC_H, null, 0, SRC_W),
+ ReferenceStrength.SOFT);
protected static final int VERTICAL_PADDING = 32;
public static final ResourceLocation DIRECTIONS_TEXTURE = new ResourceLocation(TerraConstants.MODID, "textures/directions.png");
+ protected static final int MOUSE_LEFT = 0;
+ protected static final int MOUSE_RIGHT = 1;
+
protected final GuiScreen parent;
protected Consumer whenDone;
@@ -200,7 +224,7 @@ public void drawScreen(int mouseX, int mouseY, float partialTicks) {
this.drawDefaultBackground();
this.drawCenteredString(this.fontRenderer, I18n.format(TerraConstants.MODID + ".gui.header"), this.width >> 1, VERTICAL_PADDING >> 1, 0xFFFFFFFF);
- this.preview.draw();
+ this.preview.draw(mouseX, mouseY);
{ //render list
int y = VERTICAL_PADDING;
@@ -246,11 +270,34 @@ public void drawScreen(int mouseX, int mouseY, float partialTicks) {
this.drawString(this.fontRenderer, I18n.format("terraplusplus.gui.world_size_header"), this.width - this.imgSize + 15, this.height - VERTICAL_PADDING - 30, 0xFFFFFFFF);
this.drawString(this.fontRenderer, I18n.format("terraplusplus.gui.world_size_numbers", this.worldSizeX, this.worldSizeY), this.width - this.imgSize + 15, this.height - VERTICAL_PADDING - 15, 0xFFFFFFFF);
- for(GuiButton button : this.nonTranslatedButtons) {
+ for (GuiButton button : this.nonTranslatedButtons) {
button.drawButton(this.mc, mouseX, mouseY, partialTicks);
}
}
+ /**
+ * Draws a solid color line with the specified coordinates and color.
+ */
+ public static void drawLine(int x0, int y0, int x1, int y1, int color) {
+ float f3 = (float)(color >> 24 & 255) / 255.0F;
+ float f = (float)(color >> 16 & 255) / 255.0F;
+ float f1 = (float)(color >> 8 & 255) / 255.0F;
+ float f2 = (float)(color & 255) / 255.0F;
+
+ Tessellator tessellator = Tessellator.getInstance();
+ BufferBuilder bufferbuilder = tessellator.getBuffer();
+ GlStateManager.enableBlend();
+ GlStateManager.disableTexture2D();
+ GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO);
+ GlStateManager.color(f, f1, f2, f3);
+ bufferbuilder.begin(GL11.GL_LINES, DefaultVertexFormats.POSITION);
+ bufferbuilder.pos(x0, y0, 0.0D).endVertex();
+ bufferbuilder.pos(x1, y1, 0.0D).endVertex();
+ tessellator.draw();
+ GlStateManager.enableTexture2D();
+ GlStateManager.disableBlend();
+ }
+
@Override
public void updateScreen() {
super.updateScreen();
@@ -269,14 +316,20 @@ protected void keyTyped(char typedChar, int keyCode) throws IOException {
}
}
+ protected static boolean propagateMousePressed(GuiButton button, Minecraft mc, int mouseX, int mouseY, int mouseEvent) {
+ return button instanceof RightClickableGuiButton
+ ? ((RightClickableGuiButton) button).mousePressed(mc, mouseX, mouseY, mouseEvent)
+ : mouseEvent == MOUSE_LEFT && button.mousePressed(mc, mouseX, mouseY);
+ }
+
@Override
public void mouseClicked(int mouseX, int mouseY, int mouseEvent) {
this.lastClickMoveX = mouseX;
this.lastClickMoveY = mouseY;
- if (this.doneButton.mousePressed(this.mc, mouseX, mouseY)) {
+ if (propagateMousePressed(this.doneButton, this.mc, mouseX, mouseY, mouseEvent)) {
this.whenDone.accept(this.settings.toString()); //save settings
this.mc.displayGuiScreen(this.parent); //exit
- } else if (this.cancelButton.mousePressed(this.mc, mouseX, mouseY)) {
+ } else if (propagateMousePressed(this.cancelButton, this.mc, mouseX, mouseY, mouseEvent)) {
this.mc.displayGuiScreen(this.parent); //exit without saving
} else {
boolean updateQueued = false;
@@ -288,7 +341,7 @@ public void mouseClicked(int mouseX, int mouseY, int mouseEvent) {
}
}
for (GuiButton button : this.buttonList) {
- if (button.mousePressed(this.mc, mouseX, mouseY + this.deltaY)) {
+ if (propagateMousePressed(button, this.mc, mouseX, mouseY + this.deltaY, mouseEvent)) {
updateQueued = true;
}
}
@@ -349,10 +402,10 @@ protected static class ProjectionEntry implements Entry {
protected int height = 30;
public ProjectionEntry(EarthGeneratorSettings settings, AdvancedEarthGui gui, int x, int y, int width) {
- gui.addButton(new GuiButton(0, x + (width >> 1), y, width >> 1, 20, I18n.format(TerraConstants.MODID + ".gui.transformation.add")) {
+ gui.addButton(new RightClickableGuiButton(0, x + (width >> 1), y, width >> 1, 20, I18n.format(TerraConstants.MODID + ".gui.transformation.add")) {
@Override
- public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) {
- if (super.mousePressed(mc, mouseX, mouseY)) {
+ public boolean mousePressed(Minecraft mc, int mouseX, int mouseY, int mouseEvent) {
+ if (super.mousePressed(mc, mouseX, mouseY, mouseEvent) && mouseEvent == MOUSE_LEFT) {
ProjectionEntry.this.entries.add(0, Transformation.values()[0].newSubEntry(ProjectionEntry.this, gui, 0, 0, 1));
return true;
}
@@ -453,16 +506,18 @@ protected void appendValue(StringBuilder out, int i) {
}
};
}
- };
+ },
+ ;
- static {
+ public Transformation next() {
Transformation[] values = values();
- for (int i = 0; i < values.length; i++) {
- values[i].next = values[(i + 1) % values.length];
- }
+ return values[(this.ordinal() + 1) % values.length];
}
- private Transformation next;
+ public Transformation prev() {
+ Transformation[] values = values();
+ return values[Math.floorMod(this.ordinal() - 1, values.length)];
+ }
protected TransformEntry newSubEntry(ProjectionEntry entry, AdvancedEarthGui gui, int x, int y, int width) {
return new TransformEntry(this, entry, gui, x, y, width);
@@ -493,8 +548,8 @@ public TransformEntry(Transformation transformation, ProjectionEntry entry, Adva
this.upButton = gui.addButton(new EntryButton(x, y, 20, "\u25B2") { //up
@Override
- public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) {
- if (super.mousePressed(mc, mouseX, mouseY)) {
+ public boolean mousePressed(Minecraft mc, int mouseX, int mouseY, int mouseEvent) {
+ if (super.mousePressed(mc, mouseX, mouseY, mouseEvent) && mouseEvent == MOUSE_LEFT) {
entry.entries.remove(TransformEntry.this);
entry.entries.add(0, TransformEntry.this);
return true;
@@ -504,8 +559,8 @@ public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) {
});
this.downButton = gui.addButton(new EntryButton(x + 20, y, 20, "\u25BC") { //down
@Override
- public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) {
- if (super.mousePressed(mc, mouseX, mouseY)) {
+ public boolean mousePressed(Minecraft mc, int mouseX, int mouseY, int mouseEvent) {
+ if (super.mousePressed(mc, mouseX, mouseY, mouseEvent) && mouseEvent == MOUSE_LEFT) {
entry.entries.remove(TransformEntry.this);
entry.entries.add(entry.entries.size() - 1, TransformEntry.this);
return true;
@@ -515,8 +570,8 @@ public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) {
});
this.removeButton = gui.addButton(new EntryButton(x + 40, y, 20, "\u2716") { //remove
@Override
- public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) {
- if (super.mousePressed(mc, mouseX, mouseY)) {
+ public boolean mousePressed(Minecraft mc, int mouseX, int mouseY, int mouseEvent) {
+ if (super.mousePressed(mc, mouseX, mouseY, mouseEvent) && mouseEvent == MOUSE_LEFT) {
entry.entries.remove(TransformEntry.this);
return true;
}
@@ -526,10 +581,16 @@ public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) {
this.nameButton = gui.addButton(new EntryButton(x + 60, y, width - 60, I18n.format(TerraConstants.MODID + ".gui.transformation." + transformation.name())) {
@Override
- public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) {
- if (super.mousePressed(mc, mouseX, mouseY)) {
- entry.entries.set(entry.entries.indexOf(TransformEntry.this), transformation.next.newSubEntry(entry, gui, 0, 0, 1));
- return true;
+ public boolean mousePressed(Minecraft mc, int mouseX, int mouseY, int mouseEvent) {
+ if (super.mousePressed(mc, mouseX, mouseY, mouseEvent)) {
+ switch (mouseEvent) {
+ case MOUSE_LEFT:
+ entry.entries.set(entry.entries.indexOf(TransformEntry.this), transformation.next().newSubEntry(entry, gui, 0, 0, 1));
+ return true;
+ case MOUSE_RIGHT:
+ entry.entries.set(entry.entries.indexOf(TransformEntry.this), transformation.prev().newSubEntry(entry, gui, 0, 0, 1));
+ return true;
+ }
}
return false;
}
@@ -630,86 +691,142 @@ protected static class RootEntry implements SubEntry {
protected int index;
protected final String fieldName;
- protected final Map properties;
- protected final EntryTextField[] textFields;
protected final EntryButton button;
protected final Minecraft mc = Minecraft.getMinecraft();
+ protected final DefaultParameterDescriptorGroup parameters;
+ protected final Map> parameterDescriptorsByName = new LinkedHashMap<>();
+ protected final Map parameterValuesByName = new LinkedHashMap<>();
+
+ protected final String[] parameterNames;
+ protected final EntryButton[] buttons;
+ protected final EntryTextField[] textFields;
+
public RootEntry(GeographicProjection projection, AdvancedEarthGui gui, int x, int y, int width) {
String projectionName = GlobalParseRegistries.PROJECTIONS.inverse().get(projection.getClass());
- this.initialIndex = this.index = PArrays.indexOf(PROJECTION_NAMES, projectionName);
+ this.initialIndex = this.index = PArrays.linearSearch(PROJECTION_NAMES, projectionName);
this.button = gui.addButton(new EntryButton(x, y, width, I18n.format(this.fieldName = TerraConstants.MODID + ".gui.projection." + projectionName)) {
@Override
- public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) {
- if (super.mousePressed(mc, mouseX, mouseY)) {
- RootEntry.this.index = (RootEntry.this.index + 1) % PROJECTION_NAMES.length;
- return true;
+ public boolean mousePressed(Minecraft mc, int mouseX, int mouseY, int mouseEvent) {
+ if (super.mousePressed(mc, mouseX, mouseY, mouseEvent)) {
+ switch (mouseEvent) {
+ case MOUSE_LEFT:
+ RootEntry.this.index = (RootEntry.this.index + 1) % PROJECTION_NAMES.length;
+ return true;
+ case MOUSE_RIGHT:
+ RootEntry.this.index = Math.floorMod(RootEntry.this.index - 1, PROJECTION_NAMES.length);
+ return true;
+ }
}
return false;
}
});
- this.properties = projection.properties();
+ DefaultParameterValueGroup parameterValues = new DefaultParameterValueGroup(projection.parameters());
+ this.parameters = DefaultParameterDescriptorGroup.castOrCopy(parameterValues.getDescriptor());
- int maxLen = this.properties.keySet().stream()
- .map(s -> this.fieldName + '.' + s)
- .map(I18n::format)
- .mapToInt(gui.fontRenderer::getStringWidth)
- .max().orElse(0) + 5;
+ for (GeneralParameterDescriptor parameter : this.parameters.descriptors()) {
+ this.parameterDescriptorsByName.put(parameter.getName().getCode(), (ParameterDescriptor>) parameter);
+ this.parameterValuesByName.put(parameter.getName().getCode(), parameterValues.getValue((ParameterDescriptor>) parameter));
+ }
+
+ int maxLen = this.parameterDescriptorsByName.keySet().stream()
+ .map(s -> this.fieldName + '.' + s)
+ .map(I18n::format)
+ .mapToInt(gui.fontRenderer::getStringWidth)
+ .max().orElse(0) + 5;
+
+ this.parameterNames = this.parameterDescriptorsByName.keySet().toArray(new String[0]);
+ this.textFields = new EntryTextField[this.parameterNames.length];
+ this.buttons = new EntryButton[this.parameterNames.length];
- this.textFields = new EntryTextField[this.properties.size()];
int i = 0;
- for (Map.Entry entry : this.properties.entrySet()) {
- this.textFields[i] = gui.addEntryTextField(x + maxLen, y + 20 + 2 + i * 24, width - maxLen - 2, 20);
- this.textFields[i].setText(Objects.toString(entry.getValue()));
+ for (Map.Entry entry : this.parameterValuesByName.entrySet()) {
+ ParameterDescriptor> descriptor = this.parameterDescriptorsByName.get(entry.getKey()); //yuck
+
+ int componentX = x + maxLen;
+ int componentY = y + 20 + 2 + i * 24;
+ int componentW = width - maxLen - 2;
+
+ if (CharSequence.class.isAssignableFrom(descriptor.getValueClass())) {
+ EntryTextField textField = gui.addEntryTextField(componentX, componentY, componentW, 20);
+ textField.setMaxStringLength(1 << 25);
+ textField.setText(Objects.toString(entry.getValue()));
+ this.textFields[i] = textField;
+ } else if (descriptor.getValidValues() != null || descriptor.getValueClass().isEnum()) {
+ Object[] values = descriptor.getValidValues() != null ? descriptor.getValidValues().toArray() : descriptor.getValueClass().getEnumConstants();
+ int currentIndex = notNegative(PArrays.linearSearch(values, entry.getValue()));
+
+ this.buttons[i] = gui.addButton(new EntryButton(componentX, componentY, componentW, I18n.format(this.fieldName + '.' + entry.getKey() + '.' + entry.getValue())) {
+ @Override
+ public boolean mousePressed(Minecraft mc, int mouseX, int mouseY, int mouseEvent) {
+ if (super.mousePressed(mc, mouseX, mouseY, mouseEvent)) {
+ switch (mouseEvent) {
+ case MOUSE_LEFT:
+ RootEntry.this.parameterValuesByName.put(entry.getKey(), values[(currentIndex + 1) % values.length]);
+ return true;
+ case MOUSE_RIGHT:
+ RootEntry.this.parameterValuesByName.put(entry.getKey(), values[Math.floorMod(currentIndex - 1, values.length)]);
+ return true;
+ }
+ }
+ return false;
+ }
+ });
+ } else {
+ throw new IllegalArgumentException();
+ }
i++;
}
}
@Override
public int height() {
- return 20 + 2 + this.textFields.length * 24;
+ return 20 + 2 + this.parameterValuesByName.size() * 24;
}
@Override
public void render(AdvancedEarthGui gui, int x, int y, int mouseX, int mouseY, int width) {
int i = 0;
- for (String s : this.properties.keySet()) {
+ for (String s : this.parameterDescriptorsByName.keySet()) {
gui.fontRenderer.drawString(I18n.format(this.fieldName + '.' + s), x, y + 20 + 2 + i * 24 + (20 - 8) / 2, -1, true);
i++;
}
- this.button.y = y;
for (int j = 0; j < this.textFields.length; j++) {
- this.textFields[j].y = y + 20 + 2 + j * 24;
- this.textFields[j].actuallyDrawTextBox();
+ if (this.textFields[j] != null) {
+ this.textFields[j].y = y + 20 + 2 + j * 24;
+ this.textFields[j].actuallyDrawTextBox();
+ }
}
+ for (int j = 0; j < this.buttons.length; j++) {
+ if (this.buttons[j] != null) {
+ this.buttons[j].y = y + 20 + 2 + j * 24;
+ this.buttons[j].actuallyDrawButton(this.mc, mouseX, mouseY);
+ }
+ }
+ this.button.y = y;
this.button.actuallyDrawButton(this.mc, mouseX, mouseY);
}
@Override
+ @SneakyThrows(JsonProcessingException.class)
public void toJson(StringBuilder out) {
checkArg(out.length() == 0, "must be first element in json output!");
- out.append("{\"").append(PROJECTION_NAMES[this.index]).append("\":{");
+ out.append("{\"").append(PROJECTION_NAMES[this.index]).append("\":");
+
if (this.initialIndex == this.index) {
- int i = 0;
- for (Map.Entry entry : this.properties.entrySet()) {
- if (i != 0) {
- out.append(',');
- }
- out.append('"').append(entry.getKey()).append("\":");
- boolean num = entry.getValue() instanceof Number;
- if (!num) {
- out.append('"');
- }
- out.append(this.textFields[i].getText());
- if (!num) {
- out.append('"');
+ for (int i = 0; i < this.textFields.length; i++) {
+ if (this.textFields[i] != null) {
+ this.parameterValuesByName.put(this.parameterNames[i], this.textFields[i].getText());
}
- i++;
}
+ out.append(TerraConstants.JSON_MAPPER.writeValueAsString(this.parameterValuesByName));
+ } else {
+ out.append("{}");
}
- out.append("}}");
+
+ out.append('}');
}
}
}
@@ -722,10 +839,10 @@ public ToggleEntry(AdvancedEarthGui gui, int x, int y, int width, boolean value,
this.touch = touch;
this.value = value;
- gui.addButton(new GuiButton(0, x, y, width, 20, I18n.format(TerraConstants.MODID + ".gui." + name) + ": " + I18n.format("options." + (value ? "on" : "off"))) {
+ gui.addButton(new RightClickableGuiButton(0, x, y, width, 20, I18n.format(TerraConstants.MODID + ".gui." + name) + ": " + I18n.format("options." + (value ? "on" : "off"))) {
@Override
- public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) {
- if (super.mousePressed(mc, mouseX, mouseY)) {
+ public boolean mousePressed(Minecraft mc, int mouseX, int mouseY, int mouseEvent) {
+ if (super.mousePressed(mc, mouseX, mouseY, mouseEvent) && mouseEvent == MOUSE_LEFT) {
ToggleEntry.this.value = !ToggleEntry.this.value;
return true;
}
@@ -761,10 +878,10 @@ public CWGEntry(EarthGeneratorSettings settings, AdvancedEarthGui gui, int x, in
this.text = settings.cwg();
- gui.addButton(new GuiButton(0, x + width - 20, y, 20, 20, "...") {
+ gui.addButton(new RightClickableGuiButton(0, x + width - 20, y, 20, 20, "...") {
@Override
- public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) {
- if (super.mousePressed(mc, mouseX, mouseY)) {
+ public boolean mousePressed(Minecraft mc, int mouseX, int mouseY, int mouseEvent) {
+ if (super.mousePressed(mc, mouseX, mouseY, mouseEvent) && mouseEvent == MOUSE_LEFT) {
GuiCreateWorld fakeParent = new GuiCreateWorld(null);
fakeParent.chunkProviderSettingsJson = CWGEntry.this.text;
@@ -807,10 +924,37 @@ public EarthGeneratorSettings touchSettings(EarthGeneratorSettings settings) {
}
}
+ /**
+ * A {@link GuiButton} whose {@link #mousePressed(Minecraft, int, int, int) mousePressed()} handler is also aware of the mouse button being pressed.
+ */
+ private static class RightClickableGuiButton extends GuiButton {
+ public RightClickableGuiButton(int buttonId, int x, int y, String buttonText) {
+ super(buttonId, x, y, buttonText);
+ }
+
+ public RightClickableGuiButton(int buttonId, int x, int y, int widthIn, int heightIn, String buttonText) {
+ super(buttonId, x, y, widthIn, heightIn, buttonText);
+ }
+
+ /**
+ * @deprecated use {@link #mousePressed(Minecraft, int, int, int)}
+ */
+ @Override
+ @Deprecated
+ public final boolean mousePressed(Minecraft mc, int mouseX, int mouseY) {
+ //return this.mousePressed(mc, mouseX, mouseY, MOUSE_LEFT);
+ throw new UnsupportedOperationException("must use 4-argument mousePressed() overload!");
+ }
+
+ public boolean mousePressed(Minecraft mc, int mouseX, int mouseY, int mouseEvent) {
+ return super.mousePressed(mc, mouseX, mouseY);
+ }
+ }
+
/**
* Did you have enough hacky stuff yet ?
*/
- private static class EntryButton extends GuiButton {
+ private static class EntryButton extends RightClickableGuiButton {
public EntryButton(int x, int y, int width, String buttonText) {
super(0, x, y, width, 20, buttonText);
@@ -831,8 +975,6 @@ public void drawButton(Minecraft mc, int mouseX, int mouseY, float partialTicks)
public void actuallyDrawButton(Minecraft mc, int mouseX, int mouseY) {
super.drawButton(mc, mouseX, mouseY, 0);
}
-
-
}
/**
@@ -853,8 +995,6 @@ public void drawTextBox() {
public void actuallyDrawTextBox() {
super.drawTextBox();
}
-
-
}
public static class EnumSelectionListEntry> implements Entry {
@@ -869,10 +1009,11 @@ public EnumSelectionListEntry(AdvancedEarthGui gui, int x, int y, int width, Set
this.values = EnumSet.copyOf(values);
for (T value : allValues) {
- gui.addButton(new GuiButton(0, x + 2, y + this.height, width - 2, 20, value + ": " + I18n.format("options." + (this.values.contains(value) ? "off" : "on"))) {
+ boolean contains = this.values.contains(value);
+ gui.addButton(new RightClickableGuiButton(0, x + 2, y + this.height, width - 2, 20, value + ": " + (contains ? TextFormatting.RED : TextFormatting.GREEN) + I18n.format("options." + (contains ? "off" : "on"))) {
@Override
- public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) {
- if (super.mousePressed(mc, mouseX, mouseY)) {
+ public boolean mousePressed(Minecraft mc, int mouseX, int mouseY, int mouseEvent) {
+ if (super.mousePressed(mc, mouseX, mouseY, mouseEvent) && mouseEvent == MOUSE_LEFT) {
if (!EnumSelectionListEntry.this.values.add(value)) {
EnumSelectionListEntry.this.values.remove(value);
}
@@ -903,6 +1044,13 @@ public EarthGeneratorSettings touchSettings(EarthGeneratorSettings settings) {
protected class ProjectionPreview {
private int previewX, previewY, previewWidth, previewHeight, scaling;
+
+ private double minX;
+ private double maxX;
+ private double minY;
+ private double maxY;
+ private double projScale;
+
private volatile boolean finish;
private volatile boolean reset;
private DynamicTexture previewTexture;
@@ -1006,13 +1154,16 @@ private void projectTexture(int[] dst, int width, int height, GeographicProjecti
// Scale should be able to fit whole earth inside texture
double[] bounds = projection.bounds();
- double minX = min(bounds[0], bounds[2]);
- double maxX = max(bounds[0], bounds[2]);
- double minY = min(bounds[1], bounds[3]);
- double maxY = max(bounds[1], bounds[3]);
+ double minX = this.minX = min(bounds[0], bounds[2]);
+ double maxX = this.maxX = max(bounds[0], bounds[2]);
+ double minY = this.minY = min(bounds[1], bounds[3]);
+ double maxY = this.maxY = max(bounds[1], bounds[3]);
double dx = maxX - minX;
double dy = maxY - minY;
- double scale = max(dx, dy) / (double) Math.min(width, height);
+ double scale = this.projScale = max(dx, dy) / (double) Math.min(width, height);
+
+ double[] buffer = new double[width * 2];
+ MathTransform transform = SISHelper.findOperation(SISHelper.projectedCRS(this.projection), SISHelper.tppGeoCrs()).getMathTransform();
// Actually set map data
for (int yi = 0; yi < height && !this.reset; yi++) {
@@ -1021,24 +1172,42 @@ private void projectTexture(int[] dst, int width, int height, GeographicProjecti
continue;
}
+ int bufferedCount = 0;
for (int xi = 0; xi < width; xi++) {
double x = xi * scale + minX;
if (x <= minX || x >= maxX) { //sample out of bounds, skip it
continue;
}
- try {
- double[] projected = projection.toGeo(x, y);
- int xPixel = (int) (((projected[0] + 180.0d) * (SRC_W / 360.0d)));
- int yPixel = (int) (((projected[1] + 90.0d) * (SRC_H / 180.0d)));
- if (xPixel < 0 || xPixel >= SRC_W || yPixel < 0 || yPixel >= SRC_H) { //projected sample is out of bounds
- continue;
- }
+ buffer[bufferedCount * 2 + 0] = x;
+ buffer[bufferedCount * 2 + 1] = y;
+ bufferedCount++;
+ }
+
+ SISHelper.transformManyPointsWithOutOfBoundsNaN(transform, buffer, 0, buffer, 0, bufferedCount);
+
+ for (int xi = 0, bufferIndex = 0; xi < width; xi++) {
+ double x = xi * scale + minX;
+ if (x <= minX || x >= maxX) { //sample out of bounds, skip it
+ continue;
+ }
+
+ double projectedX = buffer[bufferIndex * 2 + 0];
+ double projectedY = buffer[bufferIndex * 2 + 1];
+ bufferIndex++;
- dst[yi * width + xi] = this.src[(SRC_H - yPixel - 1) * SRC_W + xPixel];
- } catch (OutOfProjectionBoundsException ignored) {
- //sample out of bounds, skip it
+ if (Double.isNaN(projectedX) || Double.isNaN(projectedY)) {
+ continue;
}
+
+ int xPixel = (int) (((projectedX + 180.0d) * (SRC_W / 360.0d)));
+ int yPixel = (int) (((projectedY + 90.0d) * (SRC_H / 180.0d)));
+
+ if (xPixel < 0 || xPixel >= SRC_W || yPixel < 0 || yPixel >= SRC_H) { //projected sample is out of bounds
+ continue;
+ }
+
+ dst[yi * width + xi] = this.src[(SRC_H - yPixel - 1) * SRC_W + xPixel];
}
synchronized (this.textureNeedsUpdate) {
this.textureNeedsUpdate.set(true);
@@ -1067,7 +1236,7 @@ private void projectTexture(int[] dst, int width, int height, GeographicProjecti
}
}
- public void draw() {
+ public void draw(int mouseX, int mouseY) {
synchronized (this.textureNeedsUpdate) {
if (this.textureNeedsUpdate.get()) {
this.previewTexture.updateDynamicTexture();
@@ -1078,7 +1247,56 @@ public void draw() {
}
Minecraft.getMinecraft().getTextureManager().bindTexture(DIRECTIONS_TEXTURE);
drawScaledCustomSizeModalRect(this.previewX + this.previewWidth - 64, this.previewY, 0, 0, 64, 64, 64, 64, 64, 64);
+
+ int relativeMouseX = (mouseX - this.previewX) * this.scaling;
+ int relativeMouseY = (mouseY - this.previewY) * this.scaling;
+ if (relativeMouseX >= 0 && relativeMouseY >= 0 && relativeMouseX < this.previewWidth * this.scaling && relativeMouseY < this.previewHeight * this.scaling) {
+ double projX = relativeMouseX * this.projScale + this.minX;
+ double projY = relativeMouseY * this.projScale + this.minY;
+
+ MathTransform transform = SISHelper.findOperation(TerraConstants.TPP_GEO_CRS, SISHelper.projectedCRS(this.projection)).getMathTransform();
+
+ try {
+ if (true) {
+ double[] geo = this.projection.toGeo(projX, projY);
+
+ this.drawDerivativeLines(
+ Matrix2.castOrCopy(transform.derivative(new DirectPosition2D(geo[0], geo[1]))),
+ GeographicProjectionHelper.defaultDerivative(this.projection, geo[0], geo[1], true),
+ mouseX, mouseY, false);
+ } else {
+ this.drawDerivativeLines(
+ Matrix2.castOrCopy(transform.inverse().derivative(new DirectPosition2D(projX, projY))),
+ GeographicProjectionHelper.defaultDerivative(this.projection, projX, projY, false),
+ mouseX, mouseY, true);
+ }
+ } catch (TransformException e) {
+ //ignored
+ }
+ }
}
+ private void drawDerivativeLines(Matrix2 transformDerivative, Matrix2 defaultDerivative, int mouseX, int mouseY, boolean invert) {
+ if (invert) {
+ TMatrices.invertFast(defaultDerivative, defaultDerivative);
+ TMatrices.invertFast(transformDerivative, transformDerivative);
+ }
+
+ final double lineLength = 32.0d;
+
+ defaultDerivative.normalizeColumns();
+ TMatrices.scaleFast(defaultDerivative, lineLength, defaultDerivative);
+
+ GlStateManager.glLineWidth(5.0f);
+ drawLine(mouseX, mouseY, (int) (mouseX + defaultDerivative.m00), (int) (mouseY + defaultDerivative.m10), 0x8800FF00);
+ drawLine(mouseX, mouseY, (int) (mouseX + defaultDerivative.m01), (int) (mouseY + defaultDerivative.m11), 0x88FF0000);
+
+ transformDerivative.normalizeColumns();
+ TMatrices.scaleFast(transformDerivative, lineLength, transformDerivative);
+
+ GlStateManager.glLineWidth(2.0f);
+ drawLine(mouseX, mouseY, (int) (mouseX + transformDerivative.m00), (int) (mouseY + transformDerivative.m10), 0xFF00FF00);
+ drawLine(mouseX, mouseY, (int) (mouseX + transformDerivative.m01), (int) (mouseY + transformDerivative.m11), 0xFFFF0000);
+ }
}
}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/control/Command.java b/src/main/java/net/buildtheearth/terraplusplus/control/Command.java
index 060a43e1..908c07c0 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/control/Command.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/control/Command.java
@@ -1,6 +1,6 @@
package net.buildtheearth.terraplusplus.control;
-import net.buildtheearth.terraplusplus.TerraConstants;
+import net.buildtheearth.terraplusplus.util.TerraConstants;
import net.minecraft.command.CommandBase;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayer;
diff --git a/src/main/java/net/buildtheearth/terraplusplus/control/PresetEarthGui.java b/src/main/java/net/buildtheearth/terraplusplus/control/PresetEarthGui.java
index 60564d97..30ae4fc8 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/control/PresetEarthGui.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/control/PresetEarthGui.java
@@ -1,6 +1,6 @@
package net.buildtheearth.terraplusplus.control;
-import net.buildtheearth.terraplusplus.TerraConstants;
+import net.buildtheearth.terraplusplus.util.TerraConstants;
import net.buildtheearth.terraplusplus.generator.EarthGeneratorSettings;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
@@ -86,7 +86,6 @@ public void initGui() {
this.presetTextField = new GuiTextField(0, this.fontRenderer, this.width / 2 - 100, 40, 200, 20);
this.presetTextField.setMaxStringLength(Integer.MAX_VALUE);
this.setSettingsJson(this.settings);
-
}
@Override
@@ -117,6 +116,7 @@ protected void keyTyped(char typedChar, int keyCode) throws IOException {
EarthGeneratorSettings.parseUncached(newText);
this.presetTextField.setTextColor(0xFFFFFFFF);
this.doneButton.enabled = true;
+ this.setSettingsJson(newText);
} catch (Exception e) {
this.presetTextField.setTextColor(0xFFFF6060);
this.doneButton.enabled = false;
diff --git a/src/main/java/net/buildtheearth/terraplusplus/control/TerraCommand.java b/src/main/java/net/buildtheearth/terraplusplus/control/TerraCommand.java
index 7163b379..32db2e94 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/control/TerraCommand.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/control/TerraCommand.java
@@ -1,7 +1,7 @@
package net.buildtheearth.terraplusplus.control;
import com.google.common.collect.Lists;
-import net.buildtheearth.terraplusplus.TerraConstants;
+import net.buildtheearth.terraplusplus.util.TerraConstants;
import net.buildtheearth.terraplusplus.control.fragments.FragmentManager;
import net.buildtheearth.terraplusplus.control.fragments.terra.TerraConvertFragment;
import net.buildtheearth.terraplusplus.control.fragments.terra.TerraDistortionFragment;
diff --git a/src/main/java/net/buildtheearth/terraplusplus/control/TerraTeleport.java b/src/main/java/net/buildtheearth/terraplusplus/control/TerraTeleport.java
index 2d83d304..50bd2c60 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/control/TerraTeleport.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/control/TerraTeleport.java
@@ -2,15 +2,14 @@
import io.github.opencubicchunks.cubicchunks.api.worldgen.ICubeGenerator;
import io.github.opencubicchunks.cubicchunks.core.server.CubeProviderServer;
-import net.buildtheearth.terraplusplus.TerraConstants;
+import net.buildtheearth.terraplusplus.util.TerraConstants;
import net.buildtheearth.terraplusplus.dataset.IScalarDataset;
import net.buildtheearth.terraplusplus.generator.EarthGenerator;
import net.buildtheearth.terraplusplus.generator.EarthGeneratorPipelines;
import net.buildtheearth.terraplusplus.projection.OutOfProjectionBoundsException;
-import net.buildtheearth.terraplusplus.util.ChatUtil;
-import net.buildtheearth.terraplusplus.util.TranslateUtil;
+import net.buildtheearth.terraplusplus.util.TerraUtils;
import net.buildtheearth.terraplusplus.util.geo.CoordinateParseUtils;
-import net.buildtheearth.terraplusplus.util.geo.LatLng;
+import net.buildtheearth.terraplusplus.util.geo.GeographicCoordinates;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayerMP;
@@ -87,16 +86,16 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args
}
double altitude = Double.NaN;
- LatLng defaultCoords = CoordinateParseUtils.parseVerbatimCoordinates(this.getRawArguments(args).trim());
+ GeographicCoordinates defaultCoords = CoordinateParseUtils.parseVerbatimCoordinates(this.getRawArguments(args).trim());
if (defaultCoords == null) {
- LatLng possiblePlayerCoords = CoordinateParseUtils.parseVerbatimCoordinates(this.getRawArguments(this.selectArray(args, 1)));
+ GeographicCoordinates possiblePlayerCoords = CoordinateParseUtils.parseVerbatimCoordinates(this.getRawArguments(this.selectArray(args, 1)));
if (possiblePlayerCoords != null) {
defaultCoords = possiblePlayerCoords;
}
}
- LatLng possibleHeightCoords = CoordinateParseUtils.parseVerbatimCoordinates(this.getRawArguments(this.inverseSelectArray(args, args.length - 1)));
+ GeographicCoordinates possibleHeightCoords = CoordinateParseUtils.parseVerbatimCoordinates(this.getRawArguments(this.inverseSelectArray(args, args.length - 1)));
if (possibleHeightCoords != null) {
defaultCoords = possibleHeightCoords;
try {
@@ -106,7 +105,7 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args
}
}
- LatLng possibleHeightNameCoords = CoordinateParseUtils.parseVerbatimCoordinates(this.getRawArguments(this.inverseSelectArray(this.selectArray(args, 1), this.selectArray(args, 1).length - 1)));
+ GeographicCoordinates possibleHeightNameCoords = CoordinateParseUtils.parseVerbatimCoordinates(this.getRawArguments(this.inverseSelectArray(this.selectArray(args, 1), this.selectArray(args, 1).length - 1)));
if (possibleHeightNameCoords != null) {
defaultCoords = possibleHeightNameCoords;
try {
@@ -124,9 +123,9 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args
double[] proj;
try {
- proj = terrain.projection.fromGeo(defaultCoords.getLng(), defaultCoords.getLat());
+ proj = terrain.projection.fromGeo(defaultCoords.longitudeDegrees(), defaultCoords.latitudeDegrees());
} catch (Exception e) {
- sender.sendMessage(ChatUtil.combine(TextFormatting.RED, TranslateUtil.translate(TerraConstants.MODID + ".error.numbers")));
+ sender.sendMessage(TerraUtils.combine(TextFormatting.RED, TerraUtils.translate(TerraConstants.MODID + ".error.numbers")));
return;
}
@@ -135,10 +134,10 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args
try {
altFuture = terrain.datasets
.getCustom(EarthGeneratorPipelines.KEY_DATASET_HEIGHTS)
- .getAsync(defaultCoords.getLng(), defaultCoords.getLat())
+ .getAsync(defaultCoords.longitudeDegrees(), defaultCoords.latitudeDegrees())
.thenApply(a -> a + 1.0d);
} catch (OutOfProjectionBoundsException e) { //out of bounds, notify user
- sender.sendMessage(ChatUtil.titleAndCombine(TextFormatting.RED, TranslateUtil.translate(TerraConstants.MODID + ".error.numbers")));
+ sender.sendMessage(TerraUtils.titleAndCombine(TextFormatting.RED, TerraUtils.translate(TerraConstants.MODID + ".error.numbers")));
return;
}
} else {
@@ -149,18 +148,18 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args
receivers.add((EntityPlayerMP) sender);
}
List finalReceivers = receivers;
- LatLng finalDefaultCoords = defaultCoords;
+ GeographicCoordinates finalDefaultCoords = defaultCoords;
altFuture.thenAccept(s -> FMLCommonHandler.instance().getMinecraftServerInstance().addScheduledTask(() -> {
for (EntityPlayerMP p : finalReceivers) {
if (p.getName().equalsIgnoreCase(sender.getName())) {
- p.sendMessage(ChatUtil.titleAndCombine(TextFormatting.GRAY, "Teleporting to ", TextFormatting.BLUE, this.formatDecimal(finalDefaultCoords.getLat()),
- TextFormatting.GRAY, ", ", TextFormatting.BLUE, this.formatDecimal(finalDefaultCoords.getLng())));
+ p.sendMessage(TerraUtils.titleAndCombine(TextFormatting.GRAY, "Teleporting to ", TextFormatting.BLUE, this.formatDecimal(finalDefaultCoords.latitudeDegrees()),
+ TextFormatting.GRAY, ", ", TextFormatting.BLUE, this.formatDecimal(finalDefaultCoords.longitudeDegrees())));
} else if (!sender.getName().equalsIgnoreCase("@")) {
- p.sendMessage(ChatUtil.titleAndCombine(TextFormatting.GRAY, "Summoned to ", TextFormatting.BLUE, this.formatDecimal(finalDefaultCoords.getLat()),
- TextFormatting.GRAY, ", ", TextFormatting.BLUE, this.formatDecimal(finalDefaultCoords.getLng()), TextFormatting.GRAY, " by ", TextFormatting.RED, sender.getDisplayName()));
+ p.sendMessage(TerraUtils.titleAndCombine(TextFormatting.GRAY, "Summoned to ", TextFormatting.BLUE, this.formatDecimal(finalDefaultCoords.latitudeDegrees()),
+ TextFormatting.GRAY, ", ", TextFormatting.BLUE, this.formatDecimal(finalDefaultCoords.longitudeDegrees()), TextFormatting.GRAY, " by ", TextFormatting.RED, sender.getDisplayName()));
} else {
- p.sendMessage(ChatUtil.titleAndCombine(TextFormatting.GRAY, "Summoned to ", TextFormatting.BLUE, TextFormatting.BLUE, this.formatDecimal(finalDefaultCoords.getLat()),
- TextFormatting.GRAY, ", ", TextFormatting.BLUE, this.formatDecimal(finalDefaultCoords.getLng()), TextFormatting.GRAY));
+ p.sendMessage(TerraUtils.titleAndCombine(TextFormatting.GRAY, "Summoned to ", TextFormatting.BLUE, TextFormatting.BLUE, this.formatDecimal(finalDefaultCoords.latitudeDegrees()),
+ TextFormatting.GRAY, ", ", TextFormatting.BLUE, this.formatDecimal(finalDefaultCoords.longitudeDegrees()), TextFormatting.GRAY));
}
p.setPositionAndUpdate(proj[0], s, proj[1]);
}
@@ -222,9 +221,9 @@ private String getRawArguments(String[] args) {
private void usage(ICommandSender sender) {
if (this.hasPermission(sender, TerraConstants.othersCommandNode)) {
- sender.sendMessage(ChatUtil.combine(TextFormatting.RED, TranslateUtil.translate(TerraConstants.defaultCommandNode + "tpll.others.usage")));
+ sender.sendMessage(TerraUtils.combine(TextFormatting.RED, TerraUtils.translate(TerraConstants.defaultCommandNode + "tpll.others.usage")));
} else {
- sender.sendMessage(ChatUtil.combine(TextFormatting.RED, TranslateUtil.translate(TerraConstants.defaultCommandNode + "tpll.usage")));
+ sender.sendMessage(TerraUtils.combine(TextFormatting.RED, TerraUtils.translate(TerraConstants.defaultCommandNode + "tpll.usage")));
}
}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/control/fragments/FragmentManager.java b/src/main/java/net/buildtheearth/terraplusplus/control/fragments/FragmentManager.java
index ea2880bf..21b7e6f1 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/control/fragments/FragmentManager.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/control/fragments/FragmentManager.java
@@ -3,7 +3,7 @@
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import net.buildtheearth.terraplusplus.control.Command;
-import net.buildtheearth.terraplusplus.util.ChatUtil;
+import net.buildtheearth.terraplusplus.util.TerraUtils;
import net.minecraft.command.ICommandSender;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.math.BlockPos;
@@ -46,12 +46,12 @@ protected void executeFragment(MinecraftServer server, ICommandSender sender, St
private void displayCommands(ICommandSender sender) {
for (int i = 0; i < 2; i++) {
- sender.sendMessage(ChatUtil.combine(""));
+ sender.sendMessage(TerraUtils.combine(""));
}
- sender.sendMessage(ChatUtil.combine(TextFormatting.DARK_GRAY + "" + TextFormatting.STRIKETHROUGH, "================",
+ sender.sendMessage(TerraUtils.combine(TextFormatting.DARK_GRAY + "" + TextFormatting.STRIKETHROUGH, "================",
TextFormatting.DARK_GREEN + "" + TextFormatting.BOLD, " Terra++ ", TextFormatting.DARK_GRAY + "" + TextFormatting.STRIKETHROUGH, "================"));
- sender.sendMessage(ChatUtil.combine(""));
+ sender.sendMessage(TerraUtils.combine(""));
for (CommandFragment f : this.singleFragments) {
ITextComponent message = new TextComponentString(this.commandBase).setStyle(new Style().setColor(TextFormatting.YELLOW));
@@ -70,8 +70,8 @@ private void displayCommands(ICommandSender sender) {
message.appendSibling(new TextComponentString(f.getPurpose()).setStyle(new Style().setColor(TextFormatting.BLUE)));
sender.sendMessage(message);
}
- sender.sendMessage(ChatUtil.combine(""));
- sender.sendMessage(ChatUtil.combine(TextFormatting.DARK_GRAY + "" + TextFormatting.STRIKETHROUGH, "=========================================="));
+ sender.sendMessage(TerraUtils.combine(""));
+ sender.sendMessage(TerraUtils.combine(TextFormatting.DARK_GRAY + "" + TextFormatting.STRIKETHROUGH, "=========================================="));
}
@Override
diff --git a/src/main/java/net/buildtheearth/terraplusplus/control/fragments/terra/TerraConvertFragment.java b/src/main/java/net/buildtheearth/terraplusplus/control/fragments/terra/TerraConvertFragment.java
index 90e9c07e..cd9e3119 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/control/fragments/terra/TerraConvertFragment.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/control/fragments/terra/TerraConvertFragment.java
@@ -2,13 +2,12 @@
import io.github.opencubicchunks.cubicchunks.api.worldgen.ICubeGenerator;
import io.github.opencubicchunks.cubicchunks.core.server.CubeProviderServer;
-import net.buildtheearth.terraplusplus.TerraConstants;
+import net.buildtheearth.terraplusplus.util.TerraConstants;
import net.buildtheearth.terraplusplus.control.fragments.CommandFragment;
import net.buildtheearth.terraplusplus.generator.EarthGenerator;
import net.buildtheearth.terraplusplus.projection.GeographicProjection;
import net.buildtheearth.terraplusplus.projection.OutOfProjectionBoundsException;
-import net.buildtheearth.terraplusplus.util.ChatUtil;
-import net.buildtheearth.terraplusplus.util.TranslateUtil;
+import net.buildtheearth.terraplusplus.util.TerraUtils;
import net.minecraft.command.ICommandSender;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.text.TextFormatting;
@@ -22,14 +21,14 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args
IChunkProvider cp = world.getChunkProvider();
if (!(cp instanceof CubeProviderServer)) {
- sender.sendMessage(ChatUtil.getNotCC());
+ sender.sendMessage(TerraUtils.getNotCC());
return;
}
ICubeGenerator gen = ((CubeProviderServer) cp).getCubeGenerator();
if (!(gen instanceof EarthGenerator)) {
- sender.sendMessage(ChatUtil.getNotTerra());
+ sender.sendMessage(TerraUtils.getNotTerra());
return;
}
@@ -37,7 +36,7 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args
GeographicProjection projection = terrain.projection;
if (args.length < 2) {
- sender.sendMessage(ChatUtil.titleAndCombine(TextFormatting.RED, "Usage: /terra convert "));
+ sender.sendMessage(TerraUtils.titleAndCombine(TextFormatting.RED, "Usage: /terra convert "));
return;
}
@@ -47,7 +46,7 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args
x = Double.parseDouble(args[0]);
y = Double.parseDouble(args[1]);
} catch (Exception e) {
- sender.sendMessage(ChatUtil.titleAndCombine(TextFormatting.RED, TranslateUtil.translate(TerraConstants.MODID + ".error.numbers")));
+ sender.sendMessage(TerraUtils.titleAndCombine(TextFormatting.RED, TerraUtils.translate(TerraConstants.MODID + ".error.numbers")));
return;
}
@@ -60,7 +59,7 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args
} catch (OutOfProjectionBoundsException e) {
e.printStackTrace();
}
- sender.sendMessage(ChatUtil.titleAndCombine(TextFormatting.GRAY, "Result: ",
+ sender.sendMessage(TerraUtils.titleAndCombine(TextFormatting.GRAY, "Result: ",
TextFormatting.BLUE, c[0], TextFormatting.GRAY, ", ", TextFormatting.BLUE, c[1]));
} else {
try {
@@ -68,7 +67,7 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args
} catch (OutOfProjectionBoundsException e) {
e.printStackTrace();
}
- sender.sendMessage(ChatUtil.titleAndCombine(TextFormatting.GRAY, "Result: ",
+ sender.sendMessage(TerraUtils.titleAndCombine(TextFormatting.GRAY, "Result: ",
TextFormatting.BLUE, c[1], TextFormatting.GRAY, ", ", TextFormatting.BLUE, c[0]));
}
}
@@ -80,7 +79,7 @@ public String[] getName() {
@Override
public String getPurpose() {
- return TranslateUtil.translate(TerraConstants.MODID + ".fragment.terra.convert.purpose").getUnformattedComponentText();
+ return TerraUtils.translate(TerraConstants.MODID + ".fragment.terra.convert.purpose").getUnformattedComponentText();
}
@Override
diff --git a/src/main/java/net/buildtheearth/terraplusplus/control/fragments/terra/TerraDistortionFragment.java b/src/main/java/net/buildtheearth/terraplusplus/control/fragments/terra/TerraDistortionFragment.java
index a71921aa..769d9ee3 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/control/fragments/terra/TerraDistortionFragment.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/control/fragments/terra/TerraDistortionFragment.java
@@ -2,13 +2,12 @@
import io.github.opencubicchunks.cubicchunks.api.worldgen.ICubeGenerator;
import io.github.opencubicchunks.cubicchunks.core.server.CubeProviderServer;
-import net.buildtheearth.terraplusplus.TerraConstants;
+import net.buildtheearth.terraplusplus.util.TerraConstants;
import net.buildtheearth.terraplusplus.control.fragments.CommandFragment;
import net.buildtheearth.terraplusplus.generator.EarthGenerator;
import net.buildtheearth.terraplusplus.projection.GeographicProjection;
import net.buildtheearth.terraplusplus.projection.OutOfProjectionBoundsException;
-import net.buildtheearth.terraplusplus.util.ChatUtil;
-import net.buildtheearth.terraplusplus.util.TranslateUtil;
+import net.buildtheearth.terraplusplus.util.TerraUtils;
import net.minecraft.command.ICommandSender;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.text.TextFormatting;
@@ -22,14 +21,14 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args
IChunkProvider cp = world.getChunkProvider();
if (!(cp instanceof CubeProviderServer)) {
- sender.sendMessage(ChatUtil.getNotCC());
+ sender.sendMessage(TerraUtils.getNotCC());
return;
}
ICubeGenerator gen = ((CubeProviderServer) cp).getCubeGenerator();
if (!(gen instanceof EarthGenerator)) {
- sender.sendMessage(ChatUtil.getNotTerra());
+ sender.sendMessage(TerraUtils.getNotTerra());
return;
}
@@ -45,11 +44,11 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args
}
if (c == null || Double.isNaN(c[0])) {
- sender.sendMessage(ChatUtil.titleAndCombine(TextFormatting.RED, TranslateUtil.translate(TerraConstants.MODID + ".fragment.terra.where.notproj")));
+ sender.sendMessage(TerraUtils.titleAndCombine(TextFormatting.RED, TerraUtils.translate(TerraConstants.MODID + ".fragment.terra.where.notproj")));
return;
}
- sender.sendMessage(ChatUtil.titleAndCombine(TextFormatting.GRAY, "Distortion:"));
- sender.sendMessage(ChatUtil.combine(TextFormatting.RED, TranslateUtil.format(TerraConstants.MODID + ".command.terra.tissot", Math.sqrt(Math.abs(c[0])), c[1] * 180.0 / Math.PI)));
+ sender.sendMessage(TerraUtils.titleAndCombine(TextFormatting.GRAY, "Distortion:"));
+ sender.sendMessage(TerraUtils.combine(TextFormatting.RED, TerraUtils.format(TerraConstants.MODID + ".command.terra.tissot", Math.sqrt(Math.abs(c[0])), c[1] * 180.0 / Math.PI)));
}
@Override
@@ -59,7 +58,7 @@ public String[] getName() {
@Override
public String getPurpose() {
- return TranslateUtil.translate(TerraConstants.MODID + ".fragment.terra.distortion.purpose").getUnformattedComponentText();
+ return TerraUtils.translate(TerraConstants.MODID + ".fragment.terra.distortion.purpose").getUnformattedComponentText();
}
@Override
diff --git a/src/main/java/net/buildtheearth/terraplusplus/control/fragments/terra/TerraInfoFragment.java b/src/main/java/net/buildtheearth/terraplusplus/control/fragments/terra/TerraInfoFragment.java
index 5265206d..347b35dd 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/control/fragments/terra/TerraInfoFragment.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/control/fragments/terra/TerraInfoFragment.java
@@ -1,9 +1,8 @@
package net.buildtheearth.terraplusplus.control.fragments.terra;
-import net.buildtheearth.terraplusplus.TerraConstants;
+import net.buildtheearth.terraplusplus.util.TerraConstants;
import net.buildtheearth.terraplusplus.control.fragments.CommandFragment;
-import net.buildtheearth.terraplusplus.util.ChatUtil;
-import net.buildtheearth.terraplusplus.util.TranslateUtil;
+import net.buildtheearth.terraplusplus.util.TerraUtils;
import net.minecraft.command.ICommandSender;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.text.TextComponentString;
@@ -12,7 +11,7 @@
public class TerraInfoFragment extends CommandFragment {
@Override
public void execute(MinecraftServer server, ICommandSender sender, String[] args) {
- sender.sendMessage(ChatUtil.titleAndCombine(TextFormatting.GREEN, "Terra++ v", TerraConstants.VERSION,
+ sender.sendMessage(TerraUtils.titleAndCombine(TextFormatting.GREEN, "Terra++ v", TerraConstants.VERSION,
TextFormatting.GRAY, " by the ", TextFormatting.BLUE, "BTE Development Community"));
sender.sendMessage(new TextComponentString(TextFormatting.GOLD + "Original mod by orangeadam3 and shejan0"));
}
@@ -24,7 +23,7 @@ public String[] getName() {
@Override
public String getPurpose() {
- return TranslateUtil.translate(TerraConstants.MODID + ".fragment.terra.info.purpose").getUnformattedComponentText();
+ return TerraUtils.translate(TerraConstants.MODID + ".fragment.terra.info.purpose").getUnformattedComponentText();
}
@Override
diff --git a/src/main/java/net/buildtheearth/terraplusplus/control/fragments/terra/TerraWhereFragment.java b/src/main/java/net/buildtheearth/terraplusplus/control/fragments/terra/TerraWhereFragment.java
index 7716c029..3f761c61 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/control/fragments/terra/TerraWhereFragment.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/control/fragments/terra/TerraWhereFragment.java
@@ -2,14 +2,13 @@
import io.github.opencubicchunks.cubicchunks.api.worldgen.ICubeGenerator;
import io.github.opencubicchunks.cubicchunks.core.server.CubeProviderServer;
-import net.buildtheearth.terraplusplus.TerraConstants;
+import net.buildtheearth.terraplusplus.util.TerraConstants;
import net.buildtheearth.terraplusplus.control.fragments.CommandFragment;
import net.buildtheearth.terraplusplus.generator.EarthGenerator;
import net.buildtheearth.terraplusplus.projection.GeographicProjection;
import net.buildtheearth.terraplusplus.projection.OutOfProjectionBoundsException;
import net.buildtheearth.terraplusplus.util.CardinalDirection;
-import net.buildtheearth.terraplusplus.util.ChatUtil;
-import net.buildtheearth.terraplusplus.util.TranslateUtil;
+import net.buildtheearth.terraplusplus.util.TerraUtils;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.Entity;
import net.minecraft.server.MinecraftServer;
@@ -26,7 +25,7 @@ public class TerraWhereFragment extends CommandFragment {
@Override
public void execute(MinecraftServer server, ICommandSender sender, String[] args) {
if (sender instanceof MinecraftServer && args.length < 1) {
- sender.sendMessage(ChatUtil.getPlayerOnly());
+ sender.sendMessage(TerraUtils.getPlayerOnly());
return;
}
@@ -34,14 +33,14 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args
IChunkProvider cp = world.getChunkProvider();
if (!(cp instanceof CubeProviderServer)) {
- sender.sendMessage(ChatUtil.getNotCC());
+ sender.sendMessage(TerraUtils.getNotCC());
return;
}
ICubeGenerator gen = ((CubeProviderServer) cp).getCubeGenerator();
if (!(gen instanceof EarthGenerator)) {
- sender.sendMessage(ChatUtil.getNotTerra());
+ sender.sendMessage(TerraUtils.getNotTerra());
return;
}
@@ -54,7 +53,7 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args
e = sender.getEntityWorld().getPlayerEntityByName(args[0]);
}
if (e == null) {
- sender.sendMessage(ChatUtil.titleAndCombine(TextFormatting.RED, TranslateUtil.translate(TerraConstants.MODID + ".error.unknownplayer")));
+ sender.sendMessage(TerraUtils.titleAndCombine(TextFormatting.RED, TerraUtils.translate(TerraConstants.MODID + ".error.unknownplayer")));
return;
}
@@ -76,22 +75,22 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args
result = null;
azimuth = Float.NaN;
}
- sender.sendMessage(ChatUtil.titleAndCombine(TextFormatting.GRAY, "Location of ", TextFormatting.BLUE, senderName));
+ sender.sendMessage(TerraUtils.titleAndCombine(TextFormatting.GRAY, "Location of ", TextFormatting.BLUE, senderName));
if (result == null || Double.isNaN(result[0])) {
- sender.sendMessage(ChatUtil.combine(TextFormatting.RED, TranslateUtil.translate(TerraConstants.MODID + ".fragment.terra.where.notproj")));
+ sender.sendMessage(TerraUtils.combine(TextFormatting.RED, TerraUtils.translate(TerraConstants.MODID + ".fragment.terra.where.notproj")));
return;
}
if (!Float.isFinite(azimuth)) {
- sender.sendMessage(ChatUtil.combine(TextFormatting.RED, TranslateUtil.translate(TerraConstants.MODID + ".fragment.terra.where.notproj")));
+ sender.sendMessage(TerraUtils.combine(TextFormatting.RED, TerraUtils.translate(TerraConstants.MODID + ".fragment.terra.where.notproj")));
return;
}
- sender.sendMessage(ChatUtil.combine(TextFormatting.GRAY, "Location: ", TextFormatting.BLUE, result[1],
+ sender.sendMessage(TerraUtils.combine(TextFormatting.GRAY, "Location: ", TextFormatting.BLUE, result[1],
TextFormatting.GRAY, ", ", TextFormatting.BLUE, result[0]).setStyle(new Style().setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponentString("Click to copy")))
.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, String.format("%s, %s", result[1], result[0])))));
- sender.sendMessage(ChatUtil.combine(TextFormatting.GRAY, "Facing: ", TextFormatting.BLUE, CardinalDirection.azimuthToFacing(azimuth).realName(), TextFormatting.GRAY, " (", TextFormatting.BLUE, azimuth, TextFormatting.GRAY, ")"));
- sender.sendMessage(ChatUtil.combine(new TextComponentString("Open in Google Maps").setStyle(new Style().setUnderlined(true).setColor(TextFormatting.YELLOW)
+ sender.sendMessage(TerraUtils.combine(TextFormatting.GRAY, "Facing: ", TextFormatting.BLUE, CardinalDirection.azimuthToFacing(azimuth).realName(), TextFormatting.GRAY, " (", TextFormatting.BLUE, azimuth, TextFormatting.GRAY, ")"));
+ sender.sendMessage(TerraUtils.combine(new TextComponentString("Open in Google Maps").setStyle(new Style().setUnderlined(true).setColor(TextFormatting.YELLOW)
.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponentString("Open map")))
.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://www.google.com/maps/search/?api=1&query=" + result[1] + "," + result[0])))));
@@ -104,7 +103,7 @@ public String[] getName() {
@Override
public String getPurpose() {
- return TranslateUtil.translate(TerraConstants.MODID + ".fragment.terra.where.purpose").getUnformattedComponentText();
+ return TerraUtils.translate(TerraConstants.MODID + ".fragment.terra.where.purpose").getUnformattedComponentText();
}
@Override
diff --git a/src/main/java/net/buildtheearth/terraplusplus/control/fragments/terra/TerraWorldFragment.java b/src/main/java/net/buildtheearth/terraplusplus/control/fragments/terra/TerraWorldFragment.java
index 6d7d0d96..9bd5e2af 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/control/fragments/terra/TerraWorldFragment.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/control/fragments/terra/TerraWorldFragment.java
@@ -2,12 +2,11 @@
import io.github.opencubicchunks.cubicchunks.api.worldgen.ICubeGenerator;
import io.github.opencubicchunks.cubicchunks.core.server.CubeProviderServer;
-import net.buildtheearth.terraplusplus.TerraConstants;
+import net.buildtheearth.terraplusplus.util.TerraConstants;
import net.buildtheearth.terraplusplus.control.fragments.CommandFragment;
import net.buildtheearth.terraplusplus.generator.EarthGenerator;
import net.buildtheearth.terraplusplus.generator.EarthGeneratorSettings;
-import net.buildtheearth.terraplusplus.util.ChatUtil;
-import net.buildtheearth.terraplusplus.util.TranslateUtil;
+import net.buildtheearth.terraplusplus.util.TerraUtils;
import net.minecraft.command.ICommandSender;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.text.ITextComponent;
@@ -19,7 +18,7 @@
public class TerraWorldFragment extends CommandFragment {
@Override
public void execute(MinecraftServer server, ICommandSender sender, String[] args) {
- sender.sendMessage(ChatUtil.titleAndCombine(TextFormatting.RED, TranslateUtil.translate(TerraConstants.MODID + ".fragment.terra.world.header")));
+ sender.sendMessage(TerraUtils.titleAndCombine(TextFormatting.RED, TerraUtils.translate(TerraConstants.MODID + ".fragment.terra.world.header")));
World world = sender.getEntityWorld();
IChunkProvider cp = world.getChunkProvider();
@@ -38,10 +37,10 @@ public void execute(MinecraftServer server, ICommandSender sender, String[] args
EarthGeneratorSettings settings = ((EarthGenerator) gen).settings;
- sender.sendMessage(ChatUtil.combine(TextFormatting.BLUE, "World Type: ", TextFormatting.GREEN, "Earth World"));
- sender.sendMessage(ChatUtil.combine(TextFormatting.RESET));
+ sender.sendMessage(TerraUtils.combine(TextFormatting.BLUE, "World Type: ", TextFormatting.GREEN, "Earth World"));
+ sender.sendMessage(TerraUtils.combine(TextFormatting.RESET));
- sender.sendMessage(ChatUtil.combine(TextFormatting.BLUE, "Projection: ", TextFormatting.GREEN, settings.projection().toString()));
+ sender.sendMessage(TerraUtils.combine(TextFormatting.BLUE, "Projection: ", TextFormatting.GREEN, settings.projection().toString()));
sender.sendMessage(this.boolComponent("Default Heights", settings.useDefaultHeights()));
sender.sendMessage(this.boolComponent("Default Trees", settings.useDefaultTreeCover()));
}
@@ -53,7 +52,7 @@ public String[] getName() {
@Override
public String getPurpose() {
- return TranslateUtil.translate(TerraConstants.MODID + ".fragment.terra.world.purpose").getUnformattedComponentText();
+ return TerraUtils.translate(TerraConstants.MODID + ".fragment.terra.world.purpose").getUnformattedComponentText();
}
@Override
@@ -67,6 +66,6 @@ public String getPermission() {
}
private ITextComponent boolComponent(String name, boolean value) {
- return ChatUtil.combine(TextFormatting.BLUE, name, ": ", (value ? TextFormatting.GREEN + "Yes" : TextFormatting.RED + "No"));
+ return TerraUtils.combine(TextFormatting.BLUE, name, ": ", (value ? TextFormatting.GREEN + "Yes" : TextFormatting.RED + "No"));
}
}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/BlendMode.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/BlendMode.java
index 9a1263a3..36c08008 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/BlendMode.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/BlendMode.java
@@ -4,6 +4,8 @@
import lombok.AllArgsConstructor;
import lombok.NonNull;
import net.buildtheearth.terraplusplus.util.IntToDoubleBiFunction;
+import net.daporkchop.lib.math.grid.Grid2d;
+import net.daporkchop.lib.math.interpolation.CubicInterpolation;
import static java.lang.Math.*;
import static net.daporkchop.lib.common.math.PMath.*;
@@ -33,83 +35,48 @@ public double get(double scaledX, double scaledZ, @NonNull IntToDoubleBiFunction
},
@JsonAlias("SMOOTH") //old name
CUBIC(-0.5d, 3) {
- /**
- * Lerping produces visible square patches.
- *
- * Fade-curve lerping doesn't work well on steep slopes.
- *
- * Standard splines require 16 control points.
- *
- * This requires only 9 control points to produce a smooth interpolation.
- *
- * @author K.jpg
- */
- double compute(double fx, double fy, double v00, double v01, double v02, double v10, double v11, double v12, double v20, double v21, double v22) {
- // Smooth fade curve. Using this directly in a lerp wouldn't work well for steep slopes.
- // But using it here with gradient ramps does a better job.
- double xFade = fx * fx * (3.0d - 2.0d * fx);
- double yFade = fy * fy * (3.0d - 2.0d * fy);
-
- // Centerpoints of each square. The interpolator meets these values exactly.
- double vAA = (v00 + v01 + v10 + v11) * 0.25d;
- double vAB = (v01 + v02 + v11 + v12) * 0.25d;
- double vBA = (v10 + v20 + v11 + v21) * 0.25d;
- double vBB = (v11 + v21 + v12 + v22) * 0.25d;
-
- // Slopes at each centerpoint.
- // We "should" divide by 2. But we divide x and y by 2 instead for the same result.
- double vAAx = ((v10 + v11) - (v00 + v01));
- double vAAy = ((v01 + v11) - (v00 + v10));
- double vABx = ((v11 + v12) - (v01 + v02));
- double vABy = ((v02 + v12) - (v01 + v11));
- double vBAx = ((v20 + v21) - (v10 + v11));
- double vBAy = ((v11 + v21) - (v10 + v20));
- double vBBx = ((v21 + v22) - (v11 + v12));
- double vBBy = ((v12 + v22) - (v11 + v21));
-
- // This is where we correct for the doubled slopes.
- // Note that it means we need x-0.5 instead of x-1.
- fx *= 0.5d;
- fy *= 0.5d;
- double ix = fx - 0.5d;
- double iy = fy - 0.5d;
-
- // extrapolate gradients and blend
- double blendXA = (1.0d - xFade) * (vAA + vAAx * fx + vAAy * fy) + xFade * (vBA + vBAx * ix + vBAy * fy);
- double blendXB = (1.0d - xFade) * (vAB + vABx * fx + vABy * iy) + xFade * (vBB + vBBx * ix + vBBy * iy);
- return (1.0d - yFade) * blendXA + yFade * blendXB;
- }
-
@Override
public double get(double scaledX, double scaledZ, @NonNull IntToDoubleBiFunction sampler) {
- double x = scaledX - 0.5d;
- double z = scaledZ - 0.5d;
-
- //get the corners surrounding this block
- int sampleX = (int) floor(x);
- int sampleZ = (int) floor(z);
-
- double fx = x - sampleX;
- double fz = z - sampleZ;
-
- double v00 = sampler.apply(sampleX, sampleZ);
- double v01 = sampler.apply(sampleX, sampleZ + 1);
- double v02 = sampler.apply(sampleX, sampleZ + 2);
- double v10 = sampler.apply(sampleX + 1, sampleZ);
- double v11 = sampler.apply(sampleX + 1, sampleZ + 1);
- double v12 = sampler.apply(sampleX + 1, sampleZ + 2);
- double v20 = sampler.apply(sampleX + 2, sampleZ);
- double v21 = sampler.apply(sampleX + 2, sampleZ + 1);
- double v22 = sampler.apply(sampleX + 2, sampleZ + 2);
-
- //Compute smooth 9-point interpolation on this block
- double result = this.compute(fx, fz, v00, v01, v02, v10, v11, v12, v20, v21, v22);
-
- if (result > 0.0d && v00 <= 0.0d && v10 <= 0.0d && v20 <= 0.0d && v21 <= 0.0d && v11 <= 0.0d && v01 <= 0.0d && v02 <= 0.0d && v12 <= 0.0d && v22 <= 0.0d) {
- return 0.0d; //anti ocean ridges
- }
-
- return result;
+ //TODO: optimize this (eliminate allocation)
+ return CubicInterpolation.instance().getInterpolated(scaledX, scaledZ, new Grid2d() {
+ @Override
+ public int startX() {
+ return Integer.MIN_VALUE;
+ }
+
+ @Override
+ public int endX() {
+ return Integer.MAX_VALUE;
+ }
+
+ @Override
+ public int startY() {
+ return Integer.MIN_VALUE;
+ }
+
+ @Override
+ public int endY() {
+ return Integer.MAX_VALUE;
+ }
+
+ @Override
+ public double getD(int x, int y) {
+ return sampler.apply(x, y);
+ }
+
+ @Override
+ public int getI(int x, int y) {
+ return (int) sampler.apply(x, y);
+ }
+
+ @Override
+ public void setD(int x, int y, double val) {
+ }
+
+ @Override
+ public void setI(int x, int y, int val) {
+ }
+ });
}
};
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/IElementDataset.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/IElementDataset.java
index 638198ee..e3472a97 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/IElementDataset.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/IElementDataset.java
@@ -4,19 +4,33 @@
import net.buildtheearth.terraplusplus.projection.OutOfProjectionBoundsException;
import net.buildtheearth.terraplusplus.util.CornerBoundingBox2d;
+import java.lang.reflect.Array;
import java.util.concurrent.CompletableFuture;
+import static net.daporkchop.lib.common.util.PorkUtil.*;
+
/**
* A dataset consisting of arbitrary elements.
*
* @author DaPorkchop_
*/
public interface IElementDataset {
+ /**
+ * Gets an {@link IElementDataset} which contains no elements.
+ *
+ * @param type the class of the element type
+ * @return an {@link IElementDataset} which contains no elements
+ */
+ static IElementDataset empty(@NonNull Class type) {
+ return (bounds, zoom) -> CompletableFuture.completedFuture(uncheckedCast(Array.newInstance(type, 0)));
+ }
+
/**
* Gets all of the elements that intersect the given bounding box.
*
* @param bounds the bounding box
+ * @param zoom the zoom level
* @return a {@link CompletableFuture} which will be completed with the elements
*/
- CompletableFuture getAsync(@NonNull CornerBoundingBox2d bounds) throws OutOfProjectionBoundsException;
+ CompletableFuture getAsync(@NonNull CornerBoundingBox2d bounds, int zoom) throws OutOfProjectionBoundsException;
}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/IScalarDataset.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/IScalarDataset.java
index 94db1d68..8e8e994f 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/IScalarDataset.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/IScalarDataset.java
@@ -1,10 +1,9 @@
package net.buildtheearth.terraplusplus.dataset;
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import lombok.NonNull;
-import net.buildtheearth.terraplusplus.dataset.scalar.ConfigurableDoubleTiledDataset;
import net.buildtheearth.terraplusplus.projection.OutOfProjectionBoundsException;
import net.buildtheearth.terraplusplus.util.CornerBoundingBox2d;
+import net.buildtheearth.terraplusplus.util.geo.pointarray.PointArray2D;
import java.util.concurrent.CompletableFuture;
@@ -13,16 +12,7 @@
*
* @author DaPorkchop_
*/
-@JsonDeserialize(as = ConfigurableDoubleTiledDataset.class)
public interface IScalarDataset {
- /**
- * @param point the point
- * @see #getAsync(double, double)
- */
- default CompletableFuture getAsync(@NonNull double[] point) throws OutOfProjectionBoundsException {
- return this.getAsync(point[0], point[1]);
- }
-
/**
* Asynchronously gets a single value at the given point.
*
@@ -40,4 +30,19 @@ default CompletableFuture getAsync(@NonNull double[] point) throws OutOf
* @return a {@link CompletableFuture} which will be completed with the values
*/
CompletableFuture getAsync(@NonNull CornerBoundingBox2d bounds, int sizeX, int sizeZ) throws OutOfProjectionBoundsException;
+
+ /**
+ * Asynchronously gets a bunch of values at the given coordinates.
+ *
+ * @param points an array of points
+ * @return a {@link CompletableFuture} which will be completed with the values
+ */
+ CompletableFuture getAsync(@NonNull PointArray2D points) throws OutOfProjectionBoundsException;
+
+ /**
+ * @return the number of meters between sample points (in geographic/unprojected coordinate space)
+ */
+ default double[] degreesPerSample() {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/TiledDataset.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/TiledDataset.java
index bf11ada5..78db6e35 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/TiledDataset.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/TiledDataset.java
@@ -4,11 +4,11 @@
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import net.buildtheearth.terraplusplus.projection.GeographicProjection;
-import net.minecraft.util.math.ChunkPos;
+import net.buildtheearth.terraplusplus.util.TilePos;
@RequiredArgsConstructor
@Getter
-public abstract class TiledDataset extends Dataset {
+public abstract class TiledDataset extends Dataset {
@NonNull
protected final GeographicProjection projection;
protected final double tileSize;
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/TiledHttpDataset.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/TiledHttpDataset.java
index 2bd89a7d..8017ddae 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/TiledHttpDataset.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/TiledHttpDataset.java
@@ -4,9 +4,9 @@
import io.netty.buffer.ByteBuf;
import lombok.NonNull;
import net.buildtheearth.terraplusplus.projection.GeographicProjection;
+import net.buildtheearth.terraplusplus.util.TilePos;
import net.buildtheearth.terraplusplus.util.http.Http;
import net.daporkchop.lib.common.misc.string.PStrings;
-import net.minecraft.util.math.ChunkPos;
import java.util.Arrays;
import java.util.Map;
@@ -20,7 +20,7 @@ public TiledHttpDataset(@NonNull GeographicProjection projection, double tileSiz
super(projection, tileSize);
}
- protected abstract String[] urls(int tileX, int tileZ);
+ protected abstract String[] urls(int tileX, int tileZ, int zoom);
protected void addProperties(int tileX, int tileZ, @NonNull ImmutableMap.Builder builder) {
builder.put("x", String.valueOf(tileX))
@@ -34,19 +34,19 @@ protected void addProperties(int tileX, int tileZ, @NonNull ImmutableMap.Builder
protected abstract T decode(int tileX, int tileZ, @NonNull ByteBuf data) throws Exception;
@Override
- public CompletableFuture load(@NonNull ChunkPos pos) throws Exception {
- String[] urls = this.urls(pos.x, pos.z);
+ public CompletableFuture load(@NonNull TilePos pos) throws Exception {
+ String[] urls = this.urls(pos.x(), pos.z(), pos.zoom());
if (urls == null || urls.length == 0) { //no urls for tile
return CompletableFuture.completedFuture(null);
}
ImmutableMap.Builder builder = ImmutableMap.builder();
- this.addProperties(pos.x, pos.z, builder);
+ this.addProperties(pos.x(), pos.z(), builder);
Map properties = builder.build();
return Http.getFirst(
Arrays.stream(urls).map(url -> Http.formatUrl(properties, url)).toArray(String[]::new),
- data -> this.decode(pos.x, pos.z, data));
+ data -> this.decode(pos.x(), pos.z(), data));
}
}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/builtin/AbstractBuiltinDataset.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/builtin/AbstractBuiltinDataset.java
index 81163a6c..6d9ab933 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/builtin/AbstractBuiltinDataset.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/builtin/AbstractBuiltinDataset.java
@@ -4,9 +4,12 @@
import net.buildtheearth.terraplusplus.dataset.IScalarDataset;
import net.buildtheearth.terraplusplus.projection.OutOfProjectionBoundsException;
import net.buildtheearth.terraplusplus.util.CornerBoundingBox2d;
+import net.buildtheearth.terraplusplus.util.geo.pointarray.PointArray2D;
+import net.daporkchop.lib.common.pool.array.ArrayAllocator;
import java.util.concurrent.CompletableFuture;
+import static net.buildtheearth.terraplusplus.util.TerraConstants.*;
import static net.daporkchop.lib.common.util.PValidation.*;
/**
@@ -61,5 +64,33 @@ public CompletableFuture getAsync(@NonNull CornerBoundingBox2d bounds,
});
}
+ @Override
+ public CompletableFuture getAsync(@NonNull PointArray2D points) throws OutOfProjectionBoundsException {
+ if (points.size() == 0) { //no input points -> no output points, ez
+ return CompletableFuture.completedFuture(new double[0]);
+ }
+
+ return CompletableFuture.supplyAsync(() -> {
+ double scaleX = this.scaleX;
+ double scaleY = this.scaleY;
+
+ int size = points.size();
+
+ //read coordinate values into an array
+ ArrayAllocator alloc = DOUBLE_ALLOC.get();
+ double[] pointsBuffer = alloc.atLeast(points.totalValueSize());
+ points.points(pointsBuffer, 0);
+
+ //sample the value at each point and write them into a new array
+ double[] out = new double[size];
+ for (int i = 0; i < size; i++) {
+ out[i] = this.get(pointsBuffer[i * 2] * scaleX, pointsBuffer[i * 2 + 1] * scaleY);
+ }
+
+ alloc.release(pointsBuffer);
+ return out;
+ });
+ }
+
protected abstract double get(double x, double y);
}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/builtin/Climate.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/builtin/Climate.java
index 01471552..354a8927 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/builtin/Climate.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/builtin/Climate.java
@@ -7,7 +7,8 @@
import net.buildtheearth.terraplusplus.util.IntToDoubleBiFunction;
import net.daporkchop.lib.binary.oio.StreamUtil;
import net.daporkchop.lib.common.function.io.IOSupplier;
-import net.daporkchop.lib.common.ref.Ref;
+import net.daporkchop.lib.common.reference.ReferenceStrength;
+import net.daporkchop.lib.common.reference.cache.Cached;
import java.io.InputStream;
@@ -15,7 +16,7 @@ public abstract class Climate extends AbstractBuiltinDataset implements IntToDou
public static final int COLS = 720;
public static final int ROWS = 360;
- private static final Ref DATA_CACHE = Ref.soft((IOSupplier) () -> {
+ private static final Cached DATA_CACHE = Cached.global((IOSupplier) () -> {
ByteBuf buf;
try (InputStream in = new LzmaInputStream(Climate.class.getResourceAsStream("climate.lzma"))) {
buf = Unpooled.wrappedBuffer(StreamUtil.toByteArray(in));
@@ -27,7 +28,7 @@ public abstract class Climate extends AbstractBuiltinDataset implements IntToDou
out[i++] = buf.readFloat();
}
return out;
- });
+ }, ReferenceStrength.WEAK);
protected final double[] data = DATA_CACHE.get();
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/builtin/Soil.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/builtin/Soil.java
index 23554530..1d6c43b0 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/builtin/Soil.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/builtin/Soil.java
@@ -6,7 +6,8 @@
import net.buildtheearth.terraplusplus.util.RLEByteArray;
import net.daporkchop.lib.binary.oio.StreamUtil;
import net.daporkchop.lib.common.function.io.IOSupplier;
-import net.daporkchop.lib.common.ref.Ref;
+import net.daporkchop.lib.common.reference.ReferenceStrength;
+import net.daporkchop.lib.common.reference.cache.Cached;
import java.io.InputStream;
@@ -16,7 +17,7 @@ public class Soil extends AbstractBuiltinDataset {
protected static final int COLS = 10800;
protected static final int ROWS = 5400;
- private static final Ref DATA_CACHE = Ref.soft((IOSupplier) () -> {
+ private static final Cached DATA_CACHE = Cached.global((IOSupplier) () -> {
ByteBuf buf;
try (InputStream in = new LzmaInputStream(Climate.class.getResourceAsStream("soil.lzma"))) {
buf = Unpooled.wrappedBuffer(StreamUtil.toByteArray(in));
@@ -27,7 +28,7 @@ public class Soil extends AbstractBuiltinDataset {
builder.append(buf.getByte(i));
}
return builder.build();
- });
+ }, ReferenceStrength.WEAK);
private final RLEByteArray data = DATA_CACHE.get();
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/AbstractGeoJsonDeserializer.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/AbstractGeoJsonDeserializer.java
deleted file mode 100644
index 116cff45..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/AbstractGeoJsonDeserializer.java
+++ /dev/null
@@ -1,133 +0,0 @@
-package net.buildtheearth.terraplusplus.dataset.geojson;
-
-import com.google.gson.TypeAdapter;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonToken;
-import com.google.gson.stream.JsonWriter;
-import lombok.NonNull;
-import lombok.RequiredArgsConstructor;
-import net.buildtheearth.terraplusplus.dataset.geojson.geometry.GeometryCollection;
-import net.buildtheearth.terraplusplus.dataset.geojson.geometry.LineString;
-import net.buildtheearth.terraplusplus.dataset.geojson.geometry.MultiLineString;
-import net.buildtheearth.terraplusplus.dataset.geojson.geometry.MultiPoint;
-import net.buildtheearth.terraplusplus.dataset.geojson.geometry.MultiPolygon;
-import net.buildtheearth.terraplusplus.dataset.geojson.geometry.Point;
-import net.buildtheearth.terraplusplus.dataset.geojson.geometry.Polygon;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import static net.daporkchop.lib.common.util.PValidation.*;
-
-/**
- * @author DaPorkchop_
- */
-@RequiredArgsConstructor
-abstract class AbstractGeoJsonDeserializer extends TypeAdapter {
- @NonNull
- protected final String name;
-
- @Override
- public void write(JsonWriter out, T value) throws IOException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public T read(JsonReader in) throws IOException {
- in.beginObject();
- checkState("type".equals(in.nextName()), "invalid GeoJSON %s: doesn't start with type!", this.name);
-
- String type = in.nextString();
- T obj = this.read0(type, in);
- checkState(obj != null, "unknown GeoJSON %s type: \"%s\"!", this.name, type);
- in.endObject();
- return obj;
- }
-
- protected abstract T read0(String type, JsonReader in) throws IOException;
-
- protected final Geometry readGeometry(String type, JsonReader in) throws IOException {
- String fieldName = in.nextName();
-
- if ("GeometryCollection".equals(type)) { //special handling for GeometryCollection
- checkState("geometries".equals(fieldName), "unexpected field \"%s\" in GeometryCollection object", fieldName);
- List geometries = new ArrayList<>();
- in.beginArray();
- while (in.peek() != JsonToken.END_ARRAY) {
- geometries.add(this.geometryDeserializer().read(in));
- }
- in.endArray();
- return new GeometryCollection(geometries.toArray(new Geometry[0]));
- }
-
- checkState("coordinates".equals(fieldName), "unexpected field \"%s\" in %s object", fieldName, type);
- switch (type) {
- case "Point":
- return this.readPoint(in);
- case "MultiPoint":
- return new MultiPoint(this.readPoints(in));
- case "LineString":
- return this.readLineString(in);
- case "MultiLineString":
- return new MultiLineString(this.readLineStrings(in));
- case "Polygon":
- return this.readPolygon(in);
- case "MultiPolygon":
- return new MultiPolygon(this.readPolygons(in));
- }
- return null;
- }
-
- protected Point readPoint(JsonReader in) throws IOException {
- in.beginArray();
- Point point = new Point(in.nextDouble(), in.nextDouble());
- if (in.peek() == JsonToken.NUMBER) { //optional elevation
- in.nextDouble();
- }
- in.endArray();
- return point;
- }
-
- protected Point[] readPoints(JsonReader in) throws IOException {
- List points = new ArrayList<>();
- in.beginArray();
- while (in.peek() != JsonToken.END_ARRAY) {
- points.add(this.readPoint(in));
- }
- in.endArray();
- return points.toArray(new Point[0]);
- }
-
- protected LineString readLineString(JsonReader in) throws IOException {
- return new LineString(this.readPoints(in));
- }
-
- protected LineString[] readLineStrings(JsonReader in) throws IOException {
- List lines = new ArrayList<>();
- in.beginArray();
- while (in.peek() != JsonToken.END_ARRAY) {
- lines.add(this.readLineString(in));
- }
- in.endArray();
- return lines.toArray(new LineString[0]);
- }
-
- protected Polygon readPolygon(JsonReader in) throws IOException {
- LineString[] lines = this.readLineStrings(in);
- return new Polygon(lines[0], Arrays.copyOfRange(lines, 1, lines.length));
- }
-
- protected Polygon[] readPolygons(JsonReader in) throws IOException {
- List polygons = new ArrayList<>();
- in.beginArray();
- while (in.peek() != JsonToken.END_ARRAY) {
- polygons.add(this.readPolygon(in));
- }
- in.endArray();
- return polygons.toArray(new Polygon[0]);
- }
-
- protected abstract GeometryDeserializer geometryDeserializer();
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/GeoJson.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/GeoJson.java
deleted file mode 100644
index 137dc40d..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/GeoJson.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package net.buildtheearth.terraplusplus.dataset.geojson;
-
-import lombok.NonNull;
-import lombok.experimental.UtilityClass;
-import net.buildtheearth.terraplusplus.TerraConstants;
-
-import java.io.Reader;
-
-/**
- * @author DaPorkchop_
- */
-@UtilityClass
-public class GeoJson {
- /**
- * Parses a single GeoJSON object from the given {@link Reader}.
- *
- * @param in the {@link Reader} to read from
- * @return the parsed GeoJSON object
- */
- public static GeoJsonObject parse(@NonNull Reader in) {
- return TerraConstants.GSON.fromJson(in, GeoJsonObject.class);
- }
-
- /**
- * Parses a single GeoJSON object from the given {@link String}.
- *
- * @param json the {@link String} containing the JSON text
- * @return the parsed GeoJSON object
- */
- public static GeoJsonObject parse(@NonNull String json) {
- return TerraConstants.GSON.fromJson(json, GeoJsonObject.class);
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/GeoJsonObject.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/GeoJsonObject.java
index 2a25c4c7..1ffe708d 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/GeoJsonObject.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/GeoJsonObject.java
@@ -1,10 +1,35 @@
package net.buildtheearth.terraplusplus.dataset.geojson;
-import com.google.gson.annotations.JsonAdapter;
+import com.fasterxml.jackson.annotation.JsonSubTypes;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import net.buildtheearth.terraplusplus.dataset.geojson.geometry.GeometryCollection;
+import net.buildtheearth.terraplusplus.dataset.geojson.geometry.LineString;
+import net.buildtheearth.terraplusplus.dataset.geojson.geometry.MultiLineString;
+import net.buildtheearth.terraplusplus.dataset.geojson.geometry.MultiPoint;
+import net.buildtheearth.terraplusplus.dataset.geojson.geometry.MultiPolygon;
+import net.buildtheearth.terraplusplus.dataset.geojson.geometry.Point;
+import net.buildtheearth.terraplusplus.dataset.geojson.geometry.Polygon;
+import net.buildtheearth.terraplusplus.dataset.geojson.object.Feature;
+import net.buildtheearth.terraplusplus.dataset.geojson.object.FeatureCollection;
+import net.buildtheearth.terraplusplus.dataset.geojson.object.Reference;
/**
* @author DaPorkchop_
*/
-@JsonAdapter(ObjectDeserializer.class)
+@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
+@JsonSubTypes({
+ @JsonSubTypes.Type(Feature.class),
+ @JsonSubTypes.Type(FeatureCollection.class),
+ @JsonSubTypes.Type(Reference.class),
+ @JsonSubTypes.Type(GeometryCollection.class),
+ @JsonSubTypes.Type(LineString.class),
+ @JsonSubTypes.Type(MultiLineString.class),
+ @JsonSubTypes.Type(Point.class),
+ @JsonSubTypes.Type(MultiPoint.class),
+ @JsonSubTypes.Type(Polygon.class),
+ @JsonSubTypes.Type(MultiPolygon.class)
+})
+@JsonDeserialize
public interface GeoJsonObject {
}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/Geometry.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/Geometry.java
index 3117e609..1680dc66 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/Geometry.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/Geometry.java
@@ -20,8 +20,17 @@
package net.buildtheearth.terraplusplus.dataset.geojson;
-import com.google.gson.annotations.JsonAdapter;
+import com.fasterxml.jackson.annotation.JsonSubTypes;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import lombok.NonNull;
+import net.buildtheearth.terraplusplus.dataset.geojson.geometry.GeometryCollection;
+import net.buildtheearth.terraplusplus.dataset.geojson.geometry.LineString;
+import net.buildtheearth.terraplusplus.dataset.geojson.geometry.MultiLineString;
+import net.buildtheearth.terraplusplus.dataset.geojson.geometry.MultiPoint;
+import net.buildtheearth.terraplusplus.dataset.geojson.geometry.MultiPolygon;
+import net.buildtheearth.terraplusplus.dataset.geojson.geometry.Point;
+import net.buildtheearth.terraplusplus.dataset.geojson.geometry.Polygon;
import net.buildtheearth.terraplusplus.projection.OutOfProjectionBoundsException;
import net.buildtheearth.terraplusplus.projection.ProjectionFunction;
import net.buildtheearth.terraplusplus.util.bvh.Bounds2d;
@@ -29,7 +38,17 @@
/**
* @author DaPorkchop_
*/
-@JsonAdapter(GeometryDeserializer.class)
+@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
+@JsonSubTypes({
+ @JsonSubTypes.Type(GeometryCollection.class),
+ @JsonSubTypes.Type(LineString.class),
+ @JsonSubTypes.Type(MultiLineString.class),
+ @JsonSubTypes.Type(Point.class),
+ @JsonSubTypes.Type(MultiPoint.class),
+ @JsonSubTypes.Type(Polygon.class),
+ @JsonSubTypes.Type(MultiPolygon.class)
+})
+@JsonDeserialize
public interface Geometry extends GeoJsonObject {
Geometry project(@NonNull ProjectionFunction projection) throws OutOfProjectionBoundsException;
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/GeometryDeserializer.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/GeometryDeserializer.java
deleted file mode 100644
index e7314d8f..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/GeometryDeserializer.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Adapted from The MIT License (MIT)
- *
- * Copyright (c) 2020-2021 DaPorkchop_
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
- * is furnished to do so, subject to the following conditions:
- *
- * Any persons and/or organizations using this software must include the above copyright notice and this permission notice,
- * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-package net.buildtheearth.terraplusplus.dataset.geojson;
-
-import com.google.gson.stream.JsonReader;
-
-import java.io.IOException;
-
-/**
- * @author DaPorkchop_
- */
-final class GeometryDeserializer extends AbstractGeoJsonDeserializer {
- public GeometryDeserializer() {
- super("geometry");
- }
-
- @Override
- protected Geometry read0(String type, JsonReader in) throws IOException {
- return super.readGeometry(type, in);
- }
-
- @Override
- protected GeometryDeserializer geometryDeserializer() {
- return this;
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/ObjectDeserializer.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/ObjectDeserializer.java
deleted file mode 100644
index 22e2f5c2..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/ObjectDeserializer.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Adapted from The MIT License (MIT)
- *
- * Copyright (c) 2020-2021 DaPorkchop_
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
- * is furnished to do so, subject to the following conditions:
- *
- * Any persons and/or organizations using this software must include the above copyright notice and this permission notice,
- * provide sufficient credit to the original authors of the project (IE: DaPorkchop_), as well as provide a link to the original project.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-package net.buildtheearth.terraplusplus.dataset.geojson;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonToken;
-import lombok.Getter;
-import net.buildtheearth.terraplusplus.dataset.geojson.object.Feature;
-import net.buildtheearth.terraplusplus.dataset.geojson.object.FeatureCollection;
-import net.buildtheearth.terraplusplus.dataset.geojson.object.Reference;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import static net.daporkchop.lib.common.util.PValidation.*;
-
-/**
- * @author DaPorkchop_
- */
-final class ObjectDeserializer extends AbstractGeoJsonDeserializer {
- @Getter
- private final GeometryDeserializer geometryDeserializer = new GeometryDeserializer();
-
- public ObjectDeserializer() {
- super("object");
- }
-
- @Override
- protected GeoJsonObject read0(String type, JsonReader in) throws IOException {
- switch (type) {
- case "Feature":
- return this.readFeature(in);
- case "FeatureCollection":
- return this.readFeatureCollection(in);
- case "Reference":
- return this.readReference(in);
- }
-
- return super.readGeometry(type, in);
- }
-
- protected Feature readFeature(JsonReader in) throws IOException {
- Geometry geometry = null;
- Map properties = null;
- String id = null;
-
- while (in.peek() == JsonToken.NAME) {
- switch (in.nextName()) {
- case "geometry":
- geometry = this.geometryDeserializer.read(in);
- break;
- case "properties":
- if (in.peek() != JsonToken.NULL) {
- in.beginObject();
- ImmutableMap.Builder builder = ImmutableMap.builder();
- while (in.peek() != JsonToken.END_OBJECT) {
- builder.put(in.nextName(), in.nextString());
- }
- in.endObject();
- properties = builder.build();
- } else {
- in.nextNull();
- }
- break;
- case "id":
- id = in.nextString();
- break;
- default:
- throw new IllegalArgumentException("invalid field name ");
- }
- }
-
- return new Feature(geometry, properties, id);
- }
-
- protected FeatureCollection readFeatureCollection(JsonReader in) throws IOException {
- String fieldName = in.nextName();
- checkState("features".equals(fieldName), "unexpected field \"%s\" in FeatureCollection object", fieldName);
-
- List features = new ArrayList<>();
- in.beginArray();
- while (in.peek() != JsonToken.END_ARRAY) {
- in.beginObject();
-
- checkState("type".equals(in.nextName()), "invalid FeatureCollection: doesn't start with type!");
- String type = in.nextString();
- checkState("Feature".equals(type), "FeatureCollection contains non-Feature element \"%s\"", type);
- features.add(this.readFeature(in));
- in.endObject();
- }
- in.endArray();
-
- return new FeatureCollection(features.toArray(new Feature[0]));
- }
-
- protected Reference readReference(JsonReader in) throws IOException {
- String fieldName = in.nextName();
- checkState("location".equals(fieldName), "unexpected field \"%s\" in Reference object", fieldName);
-
- return new Reference(in.nextString());
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/dataset/AbstractReferenceResolvingGeoJsonDataset.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/dataset/AbstractReferenceResolvingGeoJsonDataset.java
index c250ffdf..f84be244 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/dataset/AbstractReferenceResolvingGeoJsonDataset.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/dataset/AbstractReferenceResolvingGeoJsonDataset.java
@@ -46,6 +46,10 @@ public AbstractReferenceResolvingGeoJsonDataset(
@Override
public CompletableFuture load(@NonNull String key) throws Exception {
return this.delegate.getAsync(key).thenCompose(objects -> {
+ if (objects == null) { //404 not found
+ return CompletableFuture.completedFuture(this.translate(Stream.empty()));
+ }
+
if (!areAnyObjectsReferences(objects)) { //none of the objects are references, so there's nothing to be resolved!
return CompletableFuture.completedFuture(this.translate(Arrays.stream(objects)));
}
@@ -55,7 +59,9 @@ public CompletableFuture load(@NonNull String key) throws Exception {
List> referenceFutures = new ArrayList<>();
for (GeoJsonObject object : objects) {
if (object instanceof Reference) {
- referenceFutures.add(this.getAsync(((Reference) object).location()));
+ String location = ((Reference) object).location();
+ String prefix = key.substring(0, key.indexOf('/') + 1); //TODO: this is gross
+ referenceFutures.add(this.getAsync(prefix + location));
} else {
nonReferenceObjects.add(object);
}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/dataset/ParsingGeoJsonDataset.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/dataset/ParsingGeoJsonDataset.java
index 36df33c2..59373635 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/dataset/ParsingGeoJsonDataset.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/dataset/ParsingGeoJsonDataset.java
@@ -4,12 +4,14 @@
import io.netty.buffer.ByteBufInputStream;
import lombok.NonNull;
import net.buildtheearth.terraplusplus.dataset.KeyedHttpDataset;
-import net.buildtheearth.terraplusplus.dataset.geojson.GeoJson;
import net.buildtheearth.terraplusplus.dataset.geojson.GeoJsonObject;
+import net.daporkchop.lib.common.function.io.IOFunction;
import java.io.BufferedReader;
import java.io.InputStreamReader;
+import static net.buildtheearth.terraplusplus.util.TerraConstants.*;
+
/**
* @author DaPorkchop_
*/
@@ -21,7 +23,7 @@ public ParsingGeoJsonDataset(@NonNull String[] urls) {
@Override
protected GeoJsonObject[] decode(@NonNull String path, @NonNull ByteBuf data) throws Exception {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(new ByteBufInputStream(data)))) { //parse each line as a GeoJSON object
- return reader.lines().map(GeoJson::parse).toArray(GeoJsonObject[]::new);
+ return reader.lines().map((IOFunction) s -> JSON_MAPPER.readValue(s, GeoJsonObject.class)).toArray(GeoJsonObject[]::new);
}
}
}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/dataset/TiledGeoJsonDataset.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/dataset/TiledGeoJsonDataset.java
index 176efeba..1a012d2d 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/dataset/TiledGeoJsonDataset.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/dataset/TiledGeoJsonDataset.java
@@ -8,6 +8,7 @@
import net.buildtheearth.terraplusplus.projection.EquirectangularProjection;
import net.buildtheearth.terraplusplus.projection.OutOfProjectionBoundsException;
import net.buildtheearth.terraplusplus.util.CornerBoundingBox2d;
+import net.buildtheearth.terraplusplus.util.TilePos;
import net.buildtheearth.terraplusplus.util.bvh.Bounds2d;
import net.minecraft.util.math.ChunkPos;
@@ -29,14 +30,14 @@ public TiledGeoJsonDataset(@NonNull IDataset delegate)
}
@Override
- public CompletableFuture load(@NonNull ChunkPos key) throws Exception {
- return this.delegate.getAsync(String.format("tile/%d/%d.json", key.x, key.z));
+ public CompletableFuture load(@NonNull TilePos key) throws Exception {
+ return this.delegate.getAsync(String.format("%d/tile/%d/%d.json", key.zoom(), key.x(), key.z()));
}
@Override
- public CompletableFuture getAsync(@NonNull CornerBoundingBox2d bounds) throws OutOfProjectionBoundsException {
+ public CompletableFuture getAsync(@NonNull CornerBoundingBox2d bounds, int zoom) throws OutOfProjectionBoundsException {
Bounds2d localBounds = bounds.fromGeo(this.projection).axisAlign();
- CompletableFuture[] futures = uncheckedCast(Arrays.stream(localBounds.toTiles(this.tileSize))
+ CompletableFuture[] futures = uncheckedCast(Arrays.stream(localBounds.toTiles(this.tileSize, zoom))
.map(this::getAsync)
.toArray(CompletableFuture[]::new));
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/geometry/GeometryCollection.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/geometry/GeometryCollection.java
index 478b70d0..a61e674b 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/geometry/GeometryCollection.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/geometry/GeometryCollection.java
@@ -1,8 +1,15 @@
package net.buildtheearth.terraplusplus.dataset.geojson.geometry;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonGetter;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.google.common.collect.Iterators;
-import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
import lombok.NonNull;
+import lombok.ToString;
import net.buildtheearth.terraplusplus.dataset.geojson.Geometry;
import net.buildtheearth.terraplusplus.projection.OutOfProjectionBoundsException;
import net.buildtheearth.terraplusplus.projection.ProjectionFunction;
@@ -14,11 +21,20 @@
/**
* @author DaPorkchop_
*/
-@Data
+@Getter(onMethod_ = { @JsonGetter })
+@ToString
+@EqualsAndHashCode
+@JsonDeserialize
+@JsonTypeName("GeometryCollection")
public final class GeometryCollection implements Geometry, Iterable {
- @NonNull
protected final Geometry[] geometries;
+ @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+ public GeometryCollection(
+ @JsonProperty(value = "geometries", required = true) @NonNull Geometry[] geometries) {
+ this.geometries = geometries;
+ }
+
@Override
public Iterator iterator() {
return Iterators.forArray(this.geometries);
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/geometry/LineString.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/geometry/LineString.java
index a851b30f..90a5ea46 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/geometry/LineString.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/geometry/LineString.java
@@ -1,12 +1,32 @@
package net.buildtheearth.terraplusplus.dataset.geojson.geometry;
-import lombok.Data;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonGetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.JsonToken;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
import lombok.NonNull;
+import lombok.ToString;
import net.buildtheearth.terraplusplus.dataset.geojson.Geometry;
import net.buildtheearth.terraplusplus.projection.OutOfProjectionBoundsException;
import net.buildtheearth.terraplusplus.projection.ProjectionFunction;
import net.buildtheearth.terraplusplus.util.bvh.Bounds2d;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Objects;
import static java.lang.Math.*;
@@ -15,15 +35,26 @@
/**
* @author DaPorkchop_
*/
-@Data
+@Getter
+@ToString
+@EqualsAndHashCode
+@JsonDeserialize
+@JsonTypeName("LineString")
public final class LineString implements Geometry {
+ @Getter(onMethod_ = {
+ @JsonGetter("coordinates"),
+ @JsonSerialize(using = Point.ArraySerializer.class)
+ })
protected final Point[] points;
- public LineString(@NonNull Point[] points) {
+ @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+ public LineString(
+ @JsonProperty(value = "coordinates", required = true) @JsonDeserialize(using = Point.ArrayDeserializer.class) @NonNull Point[] points) {
checkArg(points.length >= 2, "LineString must contain at least 2 points!");
this.points = points;
}
+ @JsonIgnore
public boolean isLinearRing() {
return this.points.length >= 4 && Objects.equals(this.points[0], this.points[this.points.length - 1]);
}
@@ -55,4 +86,36 @@ public Bounds2d bounds() {
}
return Bounds2d.of(minLon, maxLon, minLat, maxLat);
}
+
+ protected static final class ArrayDeserializer extends JsonDeserializer {
+ public static final ArrayDeserializer INSTANCE = new ArrayDeserializer();
+
+ @Override
+ public LineString[] deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
+ checkState(p.isExpectedStartArrayToken(), "expected array start");
+
+ List list = new ArrayList<>();
+
+ JsonToken token = p.nextToken();
+ do {
+ list.add(new LineString(Point.ArrayDeserializer.INSTANCE.deserialize(p, ctxt)));
+ } while ((token = p.nextToken()) == JsonToken.START_ARRAY);
+ checkState(token == JsonToken.END_ARRAY, "expected array end, but found %s", token);
+
+ return list.toArray(new LineString[0]);
+ }
+ }
+
+ protected static final class ArraySerializer extends JsonSerializer {
+ public static final ArraySerializer INSTANCE = new ArraySerializer();
+
+ @Override
+ public void serialize(LineString[] value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
+ gen.writeStartArray();
+ for (LineString lineString : value) {
+ Point.ArraySerializer.INSTANCE.serialize(lineString.points(), gen, serializers);
+ }
+ gen.writeEndArray();
+ }
+ }
}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/geometry/MultiLineString.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/geometry/MultiLineString.java
index 5df8ada2..2fb33d71 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/geometry/MultiLineString.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/geometry/MultiLineString.java
@@ -1,8 +1,16 @@
package net.buildtheearth.terraplusplus.dataset.geojson.geometry;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonGetter;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.collect.Iterators;
-import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
import lombok.NonNull;
+import lombok.ToString;
import net.buildtheearth.terraplusplus.dataset.geojson.Geometry;
import net.buildtheearth.terraplusplus.projection.OutOfProjectionBoundsException;
import net.buildtheearth.terraplusplus.projection.ProjectionFunction;
@@ -14,11 +22,24 @@
/**
* @author DaPorkchop_
*/
-@Data
+@Getter
+@ToString
+@EqualsAndHashCode
+@JsonDeserialize
+@JsonTypeName("MultiLineString")
public final class MultiLineString implements Geometry, Iterable {
- @NonNull
+ @Getter(onMethod_ = {
+ @JsonGetter("coordinates"),
+ @JsonSerialize(using = LineString.ArraySerializer.class)
+ })
protected final LineString[] lines;
+ @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+ public MultiLineString(
+ @JsonProperty(value = "coordinates", required = true) @JsonDeserialize(using = LineString.ArrayDeserializer.class) @NonNull LineString[] lines) {
+ this.lines = lines;
+ }
+
@Override
public Iterator iterator() {
return Iterators.forArray(this.lines);
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/geometry/MultiPoint.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/geometry/MultiPoint.java
index 7eef1910..9d5f18c8 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/geometry/MultiPoint.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/geometry/MultiPoint.java
@@ -1,8 +1,16 @@
package net.buildtheearth.terraplusplus.dataset.geojson.geometry;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonGetter;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.collect.Iterators;
-import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
import lombok.NonNull;
+import lombok.ToString;
import net.buildtheearth.terraplusplus.dataset.geojson.Geometry;
import net.buildtheearth.terraplusplus.projection.OutOfProjectionBoundsException;
import net.buildtheearth.terraplusplus.projection.ProjectionFunction;
@@ -15,11 +23,24 @@
/**
* @author DaPorkchop_
*/
-@Data
+@Getter
+@ToString
+@EqualsAndHashCode
+@JsonDeserialize
+@JsonTypeName("MultiPoint")
public final class MultiPoint implements Geometry, Iterable {
- @NonNull
+ @Getter(onMethod_ = {
+ @JsonGetter("coordinates"),
+ @JsonSerialize(using = Point.ArraySerializer.class)
+ })
protected final Point[] points;
+ @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+ public MultiPoint(
+ @JsonProperty(value = "coordinates", required = true) @JsonDeserialize(using = Point.ArrayDeserializer.class) @NonNull Point[] points) {
+ this.points = points;
+ }
+
@Override
public Iterator iterator() {
return Iterators.forArray(this.points);
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/geometry/MultiPolygon.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/geometry/MultiPolygon.java
index 111ca8ad..526ae517 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/geometry/MultiPolygon.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/geometry/MultiPolygon.java
@@ -1,8 +1,16 @@
package net.buildtheearth.terraplusplus.dataset.geojson.geometry;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonGetter;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.collect.Iterators;
-import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
import lombok.NonNull;
+import lombok.ToString;
import net.buildtheearth.terraplusplus.dataset.geojson.Geometry;
import net.buildtheearth.terraplusplus.projection.OutOfProjectionBoundsException;
import net.buildtheearth.terraplusplus.projection.ProjectionFunction;
@@ -14,11 +22,24 @@
/**
* @author DaPorkchop_
*/
-@Data
+@Getter
+@ToString
+@EqualsAndHashCode
+@JsonDeserialize
+@JsonTypeName("MultiPolygon")
public final class MultiPolygon implements Geometry, Iterable {
- @NonNull
+ @Getter(onMethod_ = {
+ @JsonGetter("coordinates"),
+ @JsonSerialize(using = Polygon.ArraySerializer.class)
+ })
protected final Polygon[] polygons;
+ @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+ public MultiPolygon(
+ @JsonProperty(value = "coordinates", required = true) @JsonDeserialize(using = Polygon.ArrayDeserializer.class) @NonNull Polygon[] polygons) {
+ this.polygons = polygons;
+ }
+
@Override
public Iterator iterator() {
return Iterators.forArray(this.polygons);
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/geometry/Point.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/geometry/Point.java
index c51a162e..ec1a24dc 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/geometry/Point.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/geometry/Point.java
@@ -1,19 +1,59 @@
package net.buildtheearth.terraplusplus.dataset.geojson.geometry;
-import lombok.Data;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonGetter;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.JsonToken;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
+import lombok.ToString;
import net.buildtheearth.terraplusplus.dataset.geojson.Geometry;
import net.buildtheearth.terraplusplus.projection.OutOfProjectionBoundsException;
import net.buildtheearth.terraplusplus.projection.ProjectionFunction;
import net.buildtheearth.terraplusplus.util.bvh.Bounds2d;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import static net.daporkchop.lib.common.util.PValidation.*;
+
/**
* @author DaPorkchop_
*/
-@Data
+@RequiredArgsConstructor
+@Getter
+@ToString
+@EqualsAndHashCode
+@JsonDeserialize
+@JsonTypeName("Point")
public final class Point implements Geometry {
- protected final double lon;
- protected final double lat;
+ protected transient final double lon;
+ protected transient final double lat;
+
+ @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+ public Point(
+ @JsonProperty(value = "coordinates", required = true) @NonNull double[] coords) {
+ checkArg(coords.length == 2 || coords.length == 3, "invalid number of point coordinates: %d", coords.length);
+ this.lon = coords[0];
+ this.lat = coords[1];
+ }
+
+ @JsonGetter("coordinates")
+ private double[] coordinates() {
+ return new double[]{ this.lon, this.lat };
+ }
@Override
public Point project(@NonNull ProjectionFunction projection) throws OutOfProjectionBoundsException {
@@ -25,4 +65,56 @@ public Point project(@NonNull ProjectionFunction projection) throws OutOfProject
public Bounds2d bounds() {
return Bounds2d.of(this.lon, this.lon, this.lat, this.lat);
}
+
+ protected static final class ArrayDeserializer extends JsonDeserializer {
+ public static final ArrayDeserializer INSTANCE = new ArrayDeserializer();
+
+ @Override
+ public Point[] deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
+ checkState(p.isExpectedStartArrayToken(), "expected array start");
+
+ List list = new ArrayList<>();
+
+ JsonToken token = p.nextToken();
+ do {
+ checkState(token == JsonToken.START_ARRAY, "expected array start, but found %s", token);
+ token = p.nextToken();
+ checkState(token.isNumeric(), "expected number, but found %s", token);
+ double lon = p.getDoubleValue();
+
+ token = p.nextToken();
+ checkState(token.isNumeric(), "expected number, but found %s", token);
+ double lat = p.getDoubleValue();
+
+ token = p.nextToken();
+ if (token != JsonToken.END_ARRAY) { //third dimension (discard it)
+ checkState(token.isNumeric(), "expected number or array end, but found %s", token);
+
+ token = p.nextToken();
+ checkState(token == JsonToken.END_ARRAY, "expected array end, but found %s", token);
+ }
+
+ list.add(new Point(lon, lat));
+ } while ((token = p.nextToken()) == JsonToken.START_ARRAY);
+ checkState(token == JsonToken.END_ARRAY, "expected array end, but found %s", token);
+
+ return list.toArray(new Point[0]);
+ }
+ }
+
+ protected static final class ArraySerializer extends JsonSerializer {
+ public static final ArraySerializer INSTANCE = new ArraySerializer();
+
+ @Override
+ public void serialize(Point[] value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
+ gen.writeStartArray();
+ for (Point point : value) {
+ gen.writeStartArray();
+ gen.writeNumber(point.lon);
+ gen.writeNumber(point.lat);
+ gen.writeEndArray();
+ }
+ gen.writeEndArray();
+ }
+ }
}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/geometry/Polygon.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/geometry/Polygon.java
index fec1865f..8ed46018 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/geometry/Polygon.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/geometry/Polygon.java
@@ -1,22 +1,62 @@
package net.buildtheearth.terraplusplus.dataset.geojson.geometry;
-import lombok.Data;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonGetter;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.JsonToken;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
import lombok.NonNull;
+import lombok.ToString;
import net.buildtheearth.terraplusplus.dataset.geojson.Geometry;
import net.buildtheearth.terraplusplus.projection.OutOfProjectionBoundsException;
import net.buildtheearth.terraplusplus.projection.ProjectionFunction;
import net.buildtheearth.terraplusplus.util.bvh.Bounds2d;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
import static net.daporkchop.lib.common.util.PValidation.*;
/**
* @author DaPorkchop_
*/
-@Data
+@Getter
+@ToString
+@EqualsAndHashCode
+@JsonDeserialize
+@JsonTypeName("Polygon")
public final class Polygon implements Geometry {
protected final LineString outerRing;
protected final LineString[] innerRings;
+ @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+ public Polygon(
+ @JsonProperty(value = "coordinates", required = true) @JsonDeserialize(using = LineString.ArrayDeserializer.class) @NonNull LineString[] rings) {
+ checkArg(rings.length >= 1, "polygon must contain at least one ring!");
+ LineString outerRing = rings[0];
+ LineString[] innerRings = Arrays.copyOfRange(rings, 1, rings.length);
+
+ checkArg(outerRing.isLinearRing(), "outerRing is not a linear ring!");
+ for (int i = 0; i < innerRings.length; i++) {
+ checkArg(innerRings[i].isLinearRing(), "innerRings[%d] is not a linear ring!", i);
+ }
+ this.outerRing = outerRing;
+ this.innerRings = innerRings;
+ }
+
public Polygon(@NonNull LineString outerRing, @NonNull LineString[] innerRings) {
checkArg(outerRing.isLinearRing(), "outerRing is not a linear ring!");
for (int i = 0; i < innerRings.length; i++) {
@@ -26,6 +66,15 @@ public Polygon(@NonNull LineString outerRing, @NonNull LineString[] innerRings)
this.innerRings = innerRings;
}
+ @JsonGetter("coordinates")
+ @JsonSerialize(using = LineString.ArraySerializer.class)
+ private LineString[] coordinates() {
+ LineString[] merged = new LineString[this.innerRings.length + 1];
+ merged[0] = this.outerRing;
+ System.arraycopy(this.innerRings, 0, merged, 1, this.innerRings.length);
+ return merged;
+ }
+
@Override
public Polygon project(@NonNull ProjectionFunction projection) throws OutOfProjectionBoundsException {
LineString outerRing = this.outerRing.project(projection);
@@ -40,4 +89,32 @@ public Polygon project(@NonNull ProjectionFunction projection) throws OutOfProje
public Bounds2d bounds() {
return this.outerRing.bounds();
}
+
+ protected static final class ArrayDeserializer extends JsonDeserializer {
+ @Override
+ public Polygon[] deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
+ checkState(p.isExpectedStartArrayToken(), "expected array start");
+
+ List list = new ArrayList<>();
+
+ JsonToken token = p.nextToken();
+ do {
+ list.add(new Polygon(LineString.ArrayDeserializer.INSTANCE.deserialize(p, ctxt)));
+ } while ((token = p.nextToken()) == JsonToken.START_ARRAY);
+ checkState(token == JsonToken.END_ARRAY, "expected array end, but found %s", token);
+
+ return list.toArray(new Polygon[0]);
+ }
+ }
+
+ protected static final class ArraySerializer extends JsonSerializer {
+ @Override
+ public void serialize(Polygon[] value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
+ gen.writeStartArray();
+ for (Polygon polygon : value) {
+ LineString.ArraySerializer.INSTANCE.serialize(polygon.coordinates(), gen, serializers);
+ }
+ gen.writeEndArray();
+ }
+ }
}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/object/Feature.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/object/Feature.java
index 42eb5a95..70e783b5 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/object/Feature.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/object/Feature.java
@@ -1,7 +1,15 @@
package net.buildtheearth.terraplusplus.dataset.geojson.object;
-import lombok.Data;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonGetter;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
import lombok.NonNull;
+import lombok.ToString;
import net.buildtheearth.terraplusplus.dataset.geojson.GeoJsonObject;
import net.buildtheearth.terraplusplus.dataset.geojson.Geometry;
@@ -10,10 +18,25 @@
/**
* @author DaPorkchop_
*/
-@Data
+@Getter(onMethod_ = { @JsonGetter })
+@ToString
+@EqualsAndHashCode
+@JsonDeserialize
+@JsonTypeName("Feature")
+@JsonInclude(JsonInclude.Include.NON_NULL)
public final class Feature implements GeoJsonObject {
@NonNull
protected final Geometry geometry;
protected final Map properties;
protected final String id;
+
+ @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+ public Feature(
+ @JsonProperty(value = "geometry", required = true) @NonNull Geometry geometry,
+ @JsonProperty("properties") Map properties,
+ @JsonProperty("id") String id) {
+ this.geometry = geometry;
+ this.properties = properties;
+ this.id = id;
+ }
}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/object/FeatureCollection.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/object/FeatureCollection.java
index 3c39d4a0..802c1354 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/object/FeatureCollection.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/object/FeatureCollection.java
@@ -1,8 +1,15 @@
package net.buildtheearth.terraplusplus.dataset.geojson.object;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonGetter;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.google.common.collect.Iterators;
-import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
import lombok.NonNull;
+import lombok.ToString;
import net.buildtheearth.terraplusplus.dataset.geojson.GeoJsonObject;
import java.util.Iterator;
@@ -10,11 +17,20 @@
/**
* @author DaPorkchop_
*/
-@Data
+@Getter(onMethod_ = { @JsonGetter })
+@ToString
+@EqualsAndHashCode
+@JsonDeserialize
+@JsonTypeName("FeatureCollection")
public final class FeatureCollection implements GeoJsonObject, Iterable {
- @NonNull
protected final Feature[] features;
+ @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+ public FeatureCollection(
+ @JsonProperty(value = "features", required = true) @NonNull Feature[] features) {
+ this.features = features;
+ }
+
@Override
public Iterator iterator() {
return Iterators.forArray(this.features);
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/object/Reference.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/object/Reference.java
index 1b868749..2343dc17 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/object/Reference.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/geojson/object/Reference.java
@@ -1,7 +1,14 @@
package net.buildtheearth.terraplusplus.dataset.geojson.object;
-import lombok.Data;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonGetter;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
import lombok.NonNull;
+import lombok.ToString;
import net.buildtheearth.terraplusplus.dataset.geojson.GeoJsonObject;
/**
@@ -9,8 +16,17 @@
*
* @author DaPorkchop_
*/
-@Data
+@Getter(onMethod_ = { @JsonGetter })
+@ToString
+@EqualsAndHashCode
+@JsonDeserialize
+@JsonTypeName("Reference")
public final class Reference implements GeoJsonObject {
- @NonNull
protected final String location;
+
+ @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+ public Reference(
+ @JsonProperty(value = "location", required = true) @NonNull String location) {
+ this.location = location;
+ }
}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/BlockStateParser.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/BlockStateParser.java
deleted file mode 100644
index 0834fbdb..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/BlockStateParser.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package net.buildtheearth.terraplusplus.dataset.osm;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonToken;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-import net.daporkchop.lib.common.function.PFunctions;
-import net.minecraft.block.Block;
-import net.minecraft.block.properties.IProperty;
-import net.minecraft.block.state.IBlockState;
-import net.minecraft.util.ResourceLocation;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-import static net.daporkchop.lib.common.util.PorkUtil.*;
-
-/**
- * Parses block states.
- *
- * @author DaPorkchop_
- */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public final class BlockStateParser extends JsonParser {
- public static final BlockStateParser INSTANCE = new BlockStateParser();
-
- @Override
- public IBlockState read(JsonReader in) throws IOException {
- ResourceLocation id = null;
- Map properties = Collections.emptyMap();
-
- in.beginObject();
- while (in.peek() != JsonToken.END_OBJECT) {
- String name = in.nextName();
- switch (name) {
- case "id":
- id = new ResourceLocation(in.nextString());
- break;
- case "properties": {
- ImmutableMap.Builder builder = ImmutableMap.builder();
- in.beginObject();
- while (in.peek() != JsonToken.END_OBJECT) {
- builder.put(in.nextName(), in.nextString());
- }
- in.endObject();
- properties = builder.build();
- break;
- }
- default:
- throw new IllegalStateException("invalid property: " + name);
- }
- }
- in.endObject();
-
- IBlockState state = Block.REGISTRY.getObject(id).getDefaultState();
- Map> lookup = state.getPropertyKeys().stream().collect(Collectors.toMap(IProperty::getName, PFunctions.identity()));
- for (Map.Entry entry : properties.entrySet()) {
- IProperty> property = lookup.get(entry.getKey());
- state = state.withProperty(property, uncheckedCast(property.parseValue(entry.getValue()).orNull()));
- }
- return state;
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/JsonParser.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/JsonParser.java
deleted file mode 100644
index ac7dbc97..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/JsonParser.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package net.buildtheearth.terraplusplus.dataset.osm;
-
-import com.google.gson.TypeAdapter;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonToken;
-import com.google.gson.stream.JsonWriter;
-import lombok.NonNull;
-import lombok.RequiredArgsConstructor;
-import net.buildtheearth.terraplusplus.TerraConstants;
-import net.daporkchop.lib.common.function.io.IOBiFunction;
-import net.daporkchop.lib.common.function.io.IOFunction;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import static net.daporkchop.lib.common.util.PValidation.*;
-
-/**
- * Base implementation of {@link TypeAdapter} for deserialzing
- *
- * @author DaPorkchop_
- */
-public abstract class JsonParser extends TypeAdapter {
- public static List readList(@NonNull JsonReader in, @NonNull IOFunction elementParser) throws IOException {
- List list = new ArrayList<>();
-
- in.beginArray();
- while (in.peek() != JsonToken.END_ARRAY) {
- list.add(elementParser.applyThrowing(in));
- }
- in.endArray();
-
- return list;
- }
-
- public static List readTypedList(@NonNull JsonReader in, @NonNull Class type) throws IOException {
- List list = new ArrayList<>();
-
- in.beginObject();
- while (in.peek() != JsonToken.END_OBJECT) {
- list.add(TerraConstants.GSON.fromJson(in, type));
- }
- in.endObject();
-
- return list;
- }
-
- public static List readTypedList(@NonNull JsonReader in, @NonNull IOBiFunction elementParser) throws IOException {
- List list = new ArrayList<>();
-
- in.beginObject();
- while (in.peek() != JsonToken.END_OBJECT) {
- list.add(elementParser.applyThrowing(in.nextName(), in));
- }
- in.endObject();
-
- return list;
- }
-
- @Override
- public void write(JsonWriter out, T value) throws IOException {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Parses values with named types.
- *
- * @author DaPorkchop_
- */
- @RequiredArgsConstructor
- private static abstract class AbstractTyped extends JsonParser implements IOBiFunction {
- @NonNull
- protected final String name;
- @NonNull
- protected final Map> types;
-
- @Override
- public T applyThrowing(String type, JsonReader in) throws IOException {
- Class extends T> clazz = this.types.get(type);
- checkArg(clazz != null, "type \"%s\" is not supported by \"%s\"!", type, this.name);
- return TerraConstants.GSON.fromJson(in, clazz);
- }
- }
-
- /**
- * Parses a single value with a named type.
- *
- * @author DaPorkchop_
- */
- public static abstract class Typed extends AbstractTyped {
- public Typed(String name, Map> types) {
- super(name, types);
- }
-
- @Override
- public T read(JsonReader in) throws IOException {
- return this.applyThrowing(in.nextName(), in);
- }
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/OSMMapper.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/OSMMapper.java
index 8d7ba28f..c0f6cf94 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/OSMMapper.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/OSMMapper.java
@@ -1,19 +1,10 @@
package net.buildtheearth.terraplusplus.dataset.osm;
-import com.google.gson.JsonParseException;
-import com.google.gson.stream.JsonReader;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import lombok.NonNull;
-import lombok.SneakyThrows;
-import net.buildtheearth.terraplusplus.TerraConstants;
import net.buildtheearth.terraplusplus.dataset.geojson.Geometry;
import net.buildtheearth.terraplusplus.dataset.vector.geometry.VectorGeometry;
-import net.buildtheearth.terraplusplus.util.http.Disk;
-import net.daporkchop.lib.binary.oio.reader.UTF8FileReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.nio.file.Files;
-import java.nio.file.Path;
import java.util.Collection;
import java.util.Map;
@@ -22,21 +13,8 @@
*
* @author DaPorkchop_
*/
+@JsonDeserialize(as = Root.class)
@FunctionalInterface
public interface OSMMapper {
- @SneakyThrows(IOException.class)
- static OSMMapper load() {
- Path path = Disk.configFile("osm.json5");
- try (JsonReader reader = new JsonReader(Files.exists(path)
- ? new UTF8FileReader(path.toString())
- : new InputStreamReader(OSMMapper.class.getResourceAsStream("osm.json5")))) {
- try {
- return TerraConstants.GSON.fromJson(reader, Root.class);
- } catch (Exception e) {
- throw new JsonParseException(reader.toString(), e);
- }
- }
- }
-
Collection apply(String id, @NonNull Map tags, @NonNull Geometry originalGeometry, @NonNull G projectedGeometry);
}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/Root.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/Root.java
index b4b1c21b..b39431e3 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/Root.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/Root.java
@@ -1,12 +1,12 @@
package net.buildtheearth.terraplusplus.dataset.osm;
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonToken;
-import lombok.Builder;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonGetter;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.Getter;
import lombok.NonNull;
-import net.buildtheearth.terraplusplus.TerraConstants;
import net.buildtheearth.terraplusplus.dataset.geojson.Geometry;
import net.buildtheearth.terraplusplus.dataset.geojson.geometry.LineString;
import net.buildtheearth.terraplusplus.dataset.geojson.geometry.MultiLineString;
@@ -14,12 +14,11 @@
import net.buildtheearth.terraplusplus.dataset.geojson.geometry.MultiPolygon;
import net.buildtheearth.terraplusplus.dataset.geojson.geometry.Point;
import net.buildtheearth.terraplusplus.dataset.geojson.geometry.Polygon;
-import net.buildtheearth.terraplusplus.dataset.osm.mapper.LineMapper;
-import net.buildtheearth.terraplusplus.dataset.osm.mapper.PolygonMapper;
+import net.buildtheearth.terraplusplus.dataset.osm.mapper.line.LineMapper;
+import net.buildtheearth.terraplusplus.dataset.osm.mapper.polygon.PolygonMapper;
import net.buildtheearth.terraplusplus.dataset.vector.geometry.VectorGeometry;
import net.daporkchop.lib.common.util.PorkUtil;
-import java.io.IOException;
import java.util.Collection;
import java.util.Map;
@@ -28,15 +27,21 @@
*
* @author DaPorkchop_
*/
-@JsonAdapter(Root.Parser.class)
-@Getter
-@Builder
+@Getter(onMethod_ = { @JsonGetter })
+@JsonDeserialize
+@JsonSerialize
final class Root implements OSMMapper {
- @NonNull
protected final LineMapper line;
- @NonNull
protected final PolygonMapper polygon;
+ @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+ public Root(
+ @JsonProperty(value = "line", required = true) @NonNull LineMapper line,
+ @JsonProperty(value = "polygon", required = true) @NonNull PolygonMapper polygon) {
+ this.line = line;
+ this.polygon = polygon;
+ }
+
@Override
public Collection apply(String id, @NonNull Map tags, @NonNull Geometry originalGeometry, @NonNull Geometry projectedGeometry) {
if (projectedGeometry instanceof Point || projectedGeometry instanceof MultiPoint) { //points can't be generated
@@ -58,33 +63,4 @@ public Collection apply(String id, @NonNull Map
throw new IllegalArgumentException("unsupported geometry type: " + PorkUtil.className(projectedGeometry));
}
}
-
- static final class Parser extends JsonParser {
- @Override
- public Root read(JsonReader in) throws IOException {
- RootBuilder builder = builder();
-
- in.beginObject();
- while (in.peek() != JsonToken.END_OBJECT) {
- String name = in.nextName();
- switch (name) {
- case "line":
- in.beginObject();
- builder.line(TerraConstants.GSON.fromJson(in, LineMapper.class));
- in.endObject();
- break;
- case "polygon":
- in.beginObject();
- builder.polygon(TerraConstants.GSON.fromJson(in, PolygonMapper.class));
- in.endObject();
- break;
- default:
- throw new IllegalStateException("invalid property: " + name);
- }
- }
- in.endObject();
-
- return builder.build();
- }
- }
}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/dvalue/BiOp.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/dvalue/BiOp.java
deleted file mode 100644
index 0fc3bd6b..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/dvalue/BiOp.java
+++ /dev/null
@@ -1,167 +0,0 @@
-package net.buildtheearth.terraplusplus.dataset.osm.dvalue;
-
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.stream.JsonReader;
-import lombok.NonNull;
-import lombok.RequiredArgsConstructor;
-
-import java.io.IOException;
-import java.util.Map;
-
-/**
- * @author DaPorkchop_
- */
-@RequiredArgsConstructor
-abstract class BiOp implements DValue {
- @NonNull
- protected final DValue first;
- @NonNull
- protected final DValue second;
-
- static abstract class Parser extends DValueParser {
- @Override
- public DValue read(JsonReader in) throws IOException {
- in.beginObject();
- DValue first = super.read(in);
- DValue second = super.read(in);
- in.endObject();
-
- return this.construct(first, second);
- }
-
- protected abstract DValue construct(@NonNull DValue first, @NonNull DValue second);
- }
-
- @JsonAdapter(Add.Parser.class)
- static final class Add extends BiOp {
- public Add(DValue first, DValue second) {
- super(first, second);
- }
-
- @Override
- public double apply(@NonNull Map tags) {
- return this.first.apply(tags) + this.second.apply(tags);
- }
-
- static class Parser extends BiOp.Parser {
- @Override
- protected DValue construct(@NonNull DValue first, @NonNull DValue second) {
- return new Add(first, second);
- }
- }
- }
-
- @JsonAdapter(Subtract.Parser.class)
- static final class Subtract extends BiOp {
- public Subtract(DValue first, DValue second) {
- super(first, second);
- }
-
- @Override
- public double apply(@NonNull Map tags) {
- return this.first.apply(tags) - this.second.apply(tags);
- }
-
- static class Parser extends BiOp.Parser {
- @Override
- protected DValue construct(@NonNull DValue first, @NonNull DValue second) {
- return new Subtract(first, second);
- }
- }
- }
-
- @JsonAdapter(Multiply.Parser.class)
- static final class Multiply extends BiOp {
- public Multiply(DValue first, DValue second) {
- super(first, second);
- }
-
- @Override
- public double apply(@NonNull Map tags) {
- return this.first.apply(tags) * this.second.apply(tags);
- }
-
- static class Parser extends BiOp.Parser {
- @Override
- protected DValue construct(@NonNull DValue first, @NonNull DValue second) {
- return new Multiply(first, second);
- }
- }
- }
-
- @JsonAdapter(Divide.Parser.class)
- static final class Divide extends BiOp {
- public Divide(DValue first, DValue second) {
- super(first, second);
- }
-
- @Override
- public double apply(@NonNull Map tags) {
- return this.first.apply(tags) / this.second.apply(tags);
- }
-
- static class Parser extends BiOp.Parser {
- @Override
- protected DValue construct(@NonNull DValue first, @NonNull DValue second) {
- return new Divide(first, second);
- }
- }
- }
-
- @JsonAdapter(FloorDiv.Parser.class)
- static final class FloorDiv extends BiOp {
- public FloorDiv(DValue first, DValue second) {
- super(first, second);
- }
-
- @Override
- public double apply(@NonNull Map tags) {
- return Math.floor(this.first.apply(tags) / this.second.apply(tags));
- }
-
- static class Parser extends BiOp.Parser {
- @Override
- protected DValue construct(@NonNull DValue first, @NonNull DValue second) {
- return new FloorDiv(first, second);
- }
- }
- }
-
- @JsonAdapter(Min.Parser.class)
- static final class Min extends BiOp {
- public Min(DValue first, DValue second) {
- super(first, second);
- }
-
- @Override
- public double apply(@NonNull Map tags) {
- return Math.min(this.first.apply(tags), this.second.apply(tags));
- }
-
- static class Parser extends BiOp.Parser {
- @Override
- protected DValue construct(@NonNull DValue first, @NonNull DValue second) {
- return new Min(first, second);
- }
- }
- }
-
- @JsonAdapter(Max.Parser.class)
- static final class Max extends BiOp {
- public Max(DValue first, DValue second) {
- super(first, second);
- }
-
- @Override
- public double apply(@NonNull Map tags) {
- return Math.max(this.first.apply(tags), this.second.apply(tags));
- }
-
- static class Parser extends BiOp.Parser {
- @Override
- protected DValue construct(@NonNull DValue first, @NonNull DValue second) {
- return new Max(first, second);
- }
- }
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/dvalue/Constant.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/dvalue/Constant.java
deleted file mode 100644
index 7f9edcaf..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/dvalue/Constant.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package net.buildtheearth.terraplusplus.dataset.osm.dvalue;
-
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.stream.JsonReader;
-import lombok.NonNull;
-import lombok.RequiredArgsConstructor;
-import net.buildtheearth.terraplusplus.dataset.osm.JsonParser;
-
-import java.io.IOException;
-import java.util.Map;
-
-/**
- * Returns a single, constant value.
- *
- * @author DaPorkchop_
- */
-@JsonAdapter(Constant.Parser.class)
-@RequiredArgsConstructor
-final class Constant implements DValue {
- protected final double value;
-
- @Override
- public double apply(@NonNull Map tags) {
- return this.value;
- }
-
- static class Parser extends JsonParser {
- @Override
- public DValue read(JsonReader in) throws IOException {
- return new Constant(in.nextDouble());
- }
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/dvalue/DValue.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/dvalue/DValue.java
index 98d0a81e..43ae9ec9 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/dvalue/DValue.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/dvalue/DValue.java
@@ -1,15 +1,26 @@
package net.buildtheearth.terraplusplus.dataset.osm.dvalue;
-import com.google.gson.annotations.JsonAdapter;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonTypeIdResolver;
import lombok.NonNull;
+import net.buildtheearth.terraplusplus.config.GlobalParseRegistries;
import java.util.Map;
/**
* @author DaPorkchop_
*/
-@JsonAdapter(DValueParser.class)
+@JsonTypeInfo(use = JsonTypeInfo.Id.CUSTOM, property = "type")
+@JsonTypeIdResolver(DValue.TypeIdResolver.class)
+@JsonDeserialize
@FunctionalInterface
public interface DValue {
double apply(@NonNull Map tags);
+
+ final class TypeIdResolver extends GlobalParseRegistries.TypeIdResolver {
+ public TypeIdResolver() {
+ super(GlobalParseRegistries.OSM_DVALUES);
+ }
+ }
}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/dvalue/DValueBinaryOperator.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/dvalue/DValueBinaryOperator.java
new file mode 100644
index 00000000..b86400fa
--- /dev/null
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/dvalue/DValueBinaryOperator.java
@@ -0,0 +1,129 @@
+package net.buildtheearth.terraplusplus.dataset.osm.dvalue;
+
+import com.fasterxml.jackson.annotation.JsonAlias;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonGetter;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
+
+import java.util.Map;
+
+/**
+ * @author DaPorkchop_
+ */
+@Getter(onMethod_ = { @JsonGetter })
+@RequiredArgsConstructor
+public abstract class DValueBinaryOperator implements DValue {
+ @NonNull
+ protected final DValue first;
+ @NonNull
+ protected final DValue second;
+
+ @JsonDeserialize
+ public static final class Add extends DValueBinaryOperator {
+ @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+ public Add(
+ @JsonProperty(value = "first", required = true) @JsonAlias({"a"}) @NonNull DValue first,
+ @JsonProperty(value = "second", required = true) @JsonAlias({"b"}) @NonNull DValue second) {
+ super(first, second);
+ }
+
+ @Override
+ public double apply(@NonNull Map tags) {
+ return this.first.apply(tags) + this.second.apply(tags);
+ }
+ }
+
+ @JsonDeserialize
+ public static final class Subtract extends DValueBinaryOperator {
+ @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+ public Subtract(
+ @JsonProperty(value = "first", required = true) @JsonAlias({"a"}) @NonNull DValue first,
+ @JsonProperty(value = "second", required = true) @JsonAlias({"b"}) @NonNull DValue second) {
+ super(first, second);
+ }
+
+ @Override
+ public double apply(@NonNull Map tags) {
+ return this.first.apply(tags) - this.second.apply(tags);
+ }
+ }
+
+ @JsonDeserialize
+ public static final class Multiply extends DValueBinaryOperator {
+ @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+ public Multiply(
+ @JsonProperty(value = "first", required = true) @JsonAlias({"a"}) @NonNull DValue first,
+ @JsonProperty(value = "second", required = true) @JsonAlias({"b"}) @NonNull DValue second) {
+ super(first, second);
+ }
+
+ @Override
+ public double apply(@NonNull Map tags) {
+ return this.first.apply(tags) * this.second.apply(tags);
+ }
+ }
+
+ @JsonDeserialize
+ public static final class Divide extends DValueBinaryOperator {
+ @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+ public Divide(
+ @JsonProperty(value = "first", required = true) @JsonAlias({"a"}) @NonNull DValue first,
+ @JsonProperty(value = "second", required = true) @JsonAlias({"b"}) @NonNull DValue second) {
+ super(first, second);
+ }
+
+ @Override
+ public double apply(@NonNull Map tags) {
+ return this.first.apply(tags) / this.second.apply(tags);
+ }
+ }
+
+ @JsonDeserialize
+ public static final class FloorDiv extends DValueBinaryOperator {
+ @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+ public FloorDiv(
+ @JsonProperty(value = "first", required = true) @JsonAlias({"a"}) @NonNull DValue first,
+ @JsonProperty(value = "second", required = true) @JsonAlias({"b"}) @NonNull DValue second) {
+ super(first, second);
+ }
+
+ @Override
+ public double apply(@NonNull Map tags) {
+ return Math.floor(this.first.apply(tags) / this.second.apply(tags));
+ }
+ }
+
+ @JsonDeserialize
+ public static final class Min extends DValueBinaryOperator {
+ @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+ public Min(
+ @JsonProperty(value = "first", required = true) @JsonAlias({"a"}) @NonNull DValue first,
+ @JsonProperty(value = "second", required = true) @JsonAlias({"b"}) @NonNull DValue second) {
+ super(first, second);
+ }
+
+ @Override
+ public double apply(@NonNull Map tags) {
+ return Math.min(this.first.apply(tags), this.second.apply(tags));
+ }
+ }
+
+ @JsonDeserialize
+ public static final class Max extends DValueBinaryOperator {
+ @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+ public Max(
+ @JsonProperty(value = "first", required = true) @JsonAlias({"a"}) @NonNull DValue first,
+ @JsonProperty(value = "second", required = true) @JsonAlias({"b"}) @NonNull DValue second) {
+ super(first, second);
+ }
+
+ @Override
+ public double apply(@NonNull Map tags) {
+ return Math.max(this.first.apply(tags), this.second.apply(tags));
+ }
+ }
+}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/config/condition/NotDC.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/dvalue/DValueConstant.java
similarity index 50%
rename from src/main/java/net/buildtheearth/terraplusplus/config/condition/NotDC.java
rename to src/main/java/net/buildtheearth/terraplusplus/dataset/osm/dvalue/DValueConstant.java
index ae9925f8..9d23fb9f 100644
--- a/src/main/java/net/buildtheearth/terraplusplus/config/condition/NotDC.java
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/dvalue/DValueConstant.java
@@ -1,4 +1,4 @@
-package net.buildtheearth.terraplusplus.config.condition;
+package net.buildtheearth.terraplusplus.dataset.osm.dvalue;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonGetter;
@@ -7,21 +7,26 @@
import lombok.Getter;
import lombok.NonNull;
+import java.util.Map;
+
/**
+ * Returns a single, constant value.
+ *
* @author DaPorkchop_
*/
-@JsonDeserialize
@Getter(onMethod_ = { @JsonGetter })
-public class NotDC implements DoubleCondition {
- protected final DoubleCondition delegate;
+@JsonDeserialize
+public final class DValueConstant implements DValue {
+ protected final double value;
@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
- public NotDC(@JsonProperty(value = "delegate", required = true) @NonNull DoubleCondition delegate) {
- this.delegate = delegate;
+ public DValueConstant(
+ @JsonProperty(value = "value", required = true) double value) {
+ this.value = value;
}
@Override
- public boolean test(double value) {
- return !this.delegate.test(value);
+ public double apply(@NonNull Map tags) {
+ return this.value;
}
}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/dvalue/DValueParser.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/dvalue/DValueParser.java
deleted file mode 100644
index a195525d..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/dvalue/DValueParser.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package net.buildtheearth.terraplusplus.dataset.osm.dvalue;
-
-import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
-import net.buildtheearth.terraplusplus.dataset.osm.JsonParser;
-
-import java.util.Map;
-
-/**
- * @author DaPorkchop_
- */
-public class DValueParser extends JsonParser.Typed {
- public static final Map> TYPES = new Object2ObjectOpenHashMap<>();
-
- static {
- TYPES.put("+", BiOp.Add.class);
- TYPES.put("-", BiOp.Subtract.class);
- TYPES.put("*", BiOp.Multiply.class);
- TYPES.put("/", BiOp.Divide.class);
-
- TYPES.put("constant", Constant.class);
- TYPES.put("floor_div", BiOp.FloorDiv.class);
- TYPES.put("min", BiOp.Min.class);
- TYPES.put("max", BiOp.Max.class);
- TYPES.put("tag", Tag.class);
- }
-
- public DValueParser() {
- super("dvalue", TYPES);
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/dvalue/DValueTag.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/dvalue/DValueTag.java
new file mode 100644
index 00000000..f88e7692
--- /dev/null
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/dvalue/DValueTag.java
@@ -0,0 +1,42 @@
+package net.buildtheearth.terraplusplus.dataset.osm.dvalue;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonGetter;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import lombok.Getter;
+import lombok.NonNull;
+
+import java.util.Map;
+
+/**
+ * Returns a single, constant value.
+ *
+ * @author DaPorkchop_
+ */
+@Getter(onMethod_ = { @JsonGetter })
+@JsonDeserialize
+public final class DValueTag implements DValue {
+ protected final String key;
+ protected final double fallback;
+
+ @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+ public DValueTag(
+ @JsonProperty(value = "key", required = true) @NonNull String key,
+ @JsonProperty(value = "fallback", required = true) double fallback) {
+ this.key = key.intern();
+ this.fallback = fallback;
+ }
+
+ @Override
+ public double apply(@NonNull Map tags) {
+ String value = tags.get(this.key);
+ if (value != null) {
+ try {
+ return Double.parseDouble(value);
+ } catch (NumberFormatException ignored) {
+ }
+ }
+ return this.fallback;
+ }
+}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/dvalue/Tag.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/dvalue/Tag.java
deleted file mode 100644
index da452c8e..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/dvalue/Tag.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package net.buildtheearth.terraplusplus.dataset.osm.dvalue;
-
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonToken;
-import lombok.Builder;
-import lombok.NonNull;
-import net.buildtheearth.terraplusplus.dataset.osm.JsonParser;
-
-import java.io.IOException;
-import java.util.Map;
-
-/**
- * Returns a single, constant value.
- *
- * @author DaPorkchop_
- */
-@JsonAdapter(Tag.Parser.class)
-@Builder
-final class Tag implements DValue {
- @NonNull
- protected final String key;
- protected final double fallback;
-
- @Override
- public double apply(@NonNull Map tags) {
- String value = tags.get(this.key);
- if (value != null) {
- try {
- return Double.parseDouble(value);
- } catch (NumberFormatException ignored) {
- }
- }
- return this.fallback;
- }
-
- static class Parser extends JsonParser {
- @Override
- public DValue read(JsonReader in) throws IOException {
- TagBuilder builder = builder();
-
- in.beginObject();
- while (in.peek() != JsonToken.END_OBJECT) {
- String name = in.nextName();
- switch (name) {
- case "key":
- builder.key(in.nextString().intern());
- break;
- case "fallback":
- builder.fallback(in.nextDouble());
- break;
- default:
- throw new IllegalStateException("invalid property: " + name);
- }
- }
- in.endObject();
-
- return builder.build();
- }
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/mapper/AbstractMapperAll.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/mapper/AbstractMapperAll.java
new file mode 100644
index 00000000..7786c2fa
--- /dev/null
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/mapper/AbstractMapperAll.java
@@ -0,0 +1,41 @@
+package net.buildtheearth.terraplusplus.dataset.osm.mapper;
+
+import com.fasterxml.jackson.annotation.JsonGetter;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NonNull;
+import net.buildtheearth.terraplusplus.dataset.geojson.Geometry;
+import net.buildtheearth.terraplusplus.dataset.osm.OSMMapper;
+import net.buildtheearth.terraplusplus.dataset.vector.geometry.VectorGeometry;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Returns the combined results of all of a number of mappers, or {@code null} if any one of them returns {@code null}.
+ *
+ * @author DaPorkchop_
+ */
+@Getter(onMethod_ = { @JsonGetter })
+@AllArgsConstructor
+public abstract class AbstractMapperAll> implements OSMMapper {
+ @NonNull
+ protected final M[] children;
+
+ @Override
+ public Collection apply(String id, @NonNull Map tags, @NonNull Geometry originalGeometry, @NonNull G projectedGeometry) {
+ List out = new ArrayList<>();
+ int i = 0;
+ for (M child : this.children) {
+ Collection result = child.apply(id + '/' + i++, tags, originalGeometry, projectedGeometry);
+ if (result == null) { //don't bother processing further children
+ return null;
+ }
+ out.addAll(result);
+ }
+
+ return out;
+ }
+}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/mapper/AbstractMapperAny.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/mapper/AbstractMapperAny.java
new file mode 100644
index 00000000..971bba21
--- /dev/null
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/mapper/AbstractMapperAny.java
@@ -0,0 +1,40 @@
+package net.buildtheearth.terraplusplus.dataset.osm.mapper;
+
+import com.fasterxml.jackson.annotation.JsonGetter;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NonNull;
+import net.buildtheearth.terraplusplus.dataset.geojson.Geometry;
+import net.buildtheearth.terraplusplus.dataset.osm.OSMMapper;
+import net.buildtheearth.terraplusplus.dataset.vector.geometry.VectorGeometry;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Returns the combined results of all of a number of mappers, ignoring any one of them that returns {@code null}.
+ *
+ * @author DaPorkchop_
+ */
+@Getter(onMethod_ = { @JsonGetter })
+@AllArgsConstructor
+public abstract class AbstractMapperAny> implements OSMMapper {
+ @NonNull
+ protected final M[] children;
+
+ @Override
+ public Collection apply(String id, @NonNull Map tags, @NonNull Geometry originalGeometry, @NonNull G projectedGeometry) {
+ List out = new ArrayList<>();
+ int i = 0;
+ for (M child : this.children) {
+ Collection result = child.apply(id + '/' + i++, tags, originalGeometry, projectedGeometry);
+ if (result != null) { //don't bother processing further children
+ out.addAll(result);
+ }
+ }
+
+ return out;
+ }
+}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/mapper/AbstractMapperCondition.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/mapper/AbstractMapperCondition.java
new file mode 100644
index 00000000..bc044c78
--- /dev/null
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/mapper/AbstractMapperCondition.java
@@ -0,0 +1,36 @@
+package net.buildtheearth.terraplusplus.dataset.osm.mapper;
+
+import com.fasterxml.jackson.annotation.JsonGetter;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NonNull;
+import net.buildtheearth.terraplusplus.dataset.geojson.Geometry;
+import net.buildtheearth.terraplusplus.dataset.osm.OSMMapper;
+import net.buildtheearth.terraplusplus.dataset.osm.match.MatchCondition;
+import net.buildtheearth.terraplusplus.dataset.vector.geometry.VectorGeometry;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * Forwards elements to another mapper if a given {@link MatchCondition} matches.
+ *
+ * @author DaPorkchop_
+ */
+@Getter(onMethod_ = { @JsonGetter })
+@AllArgsConstructor
+public abstract class AbstractMapperCondition> implements OSMMapper {
+ @NonNull
+ protected final MatchCondition match;
+ @NonNull
+ protected final M emit;
+
+ @Override
+ public Collection apply(String id, @NonNull Map tags, @NonNull Geometry originalGeometry, @NonNull G projectedGeometry) {
+ if (!this.match.test(id, tags, originalGeometry, projectedGeometry)) { //element doesn't match, emit nothing
+ return null;
+ }
+
+ return this.emit.apply(id, tags, originalGeometry, projectedGeometry);
+ }
+}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/mapper/AbstractMapperFirst.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/mapper/AbstractMapperFirst.java
new file mode 100644
index 00000000..00d9f6db
--- /dev/null
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/mapper/AbstractMapperFirst.java
@@ -0,0 +1,36 @@
+package net.buildtheearth.terraplusplus.dataset.osm.mapper;
+
+import com.fasterxml.jackson.annotation.JsonGetter;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NonNull;
+import net.buildtheearth.terraplusplus.dataset.geojson.Geometry;
+import net.buildtheearth.terraplusplus.dataset.osm.OSMMapper;
+import net.buildtheearth.terraplusplus.dataset.vector.geometry.VectorGeometry;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * Returns the result of the first of a number of mappers that returned a non-{@code null} value.
+ *
+ * @author DaPorkchop_
+ */
+@Getter(onMethod_ = { @JsonGetter })
+@AllArgsConstructor
+public abstract class AbstractMapperFirst> implements OSMMapper {
+ @NonNull
+ protected final M[] children;
+
+ @Override
+ public Collection apply(String id, @NonNull Map tags, @NonNull Geometry originalGeometry, @NonNull G projectedGeometry) {
+ for (M child : this.children) {
+ Collection result = child.apply(id, tags, originalGeometry, projectedGeometry);
+ if (result != null) {
+ return result;
+ }
+ }
+
+ return null; //none matched!
+ }
+}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/mapper/AbstractMapperNothing.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/mapper/AbstractMapperNothing.java
new file mode 100644
index 00000000..2e1ec5b4
--- /dev/null
+++ b/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/mapper/AbstractMapperNothing.java
@@ -0,0 +1,22 @@
+package net.buildtheearth.terraplusplus.dataset.osm.mapper;
+
+import lombok.NonNull;
+import net.buildtheearth.terraplusplus.dataset.geojson.Geometry;
+import net.buildtheearth.terraplusplus.dataset.osm.OSMMapper;
+import net.buildtheearth.terraplusplus.dataset.vector.geometry.VectorGeometry;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * Returns a non-null, empty list.
+ *
+ * @author DaPorkchop_
+ */
+public abstract class AbstractMapperNothing> implements OSMMapper {
+ @Override
+ public Collection apply(String id, @NonNull Map tags, @NonNull Geometry originalGeometry, @NonNull G projectedGeometry) {
+ return Collections.emptyList();
+ }
+}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/mapper/All.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/mapper/All.java
deleted file mode 100644
index 7cbc7f55..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/mapper/All.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package net.buildtheearth.terraplusplus.dataset.osm.mapper;
-
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.stream.JsonReader;
-import lombok.AllArgsConstructor;
-import lombok.NonNull;
-import net.buildtheearth.terraplusplus.dataset.geojson.Geometry;
-import net.buildtheearth.terraplusplus.dataset.geojson.geometry.MultiLineString;
-import net.buildtheearth.terraplusplus.dataset.geojson.geometry.MultiPolygon;
-import net.buildtheearth.terraplusplus.dataset.osm.JsonParser;
-import net.buildtheearth.terraplusplus.dataset.osm.OSMMapper;
-import net.buildtheearth.terraplusplus.dataset.vector.geometry.VectorGeometry;
-import net.daporkchop.lib.common.util.GenericMatcher;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-import static net.daporkchop.lib.common.util.PValidation.*;
-
-/**
- * Returns the combined results of all of a number of mappers, or {@code null} if any one of them returns {@code null}.
- *
- * @author DaPorkchop_
- */
-@AllArgsConstructor
-abstract class All> implements OSMMapper {
- @NonNull
- protected final M[] children;
-
- @Override
- public Collection apply(String id, @NonNull Map tags, @NonNull Geometry originalGeometry, @NonNull G projectedGeometry) {
- List out = new ArrayList<>();
- int i = 0;
- for (M child : this.children) {
- Collection result = child.apply(id + '/' + i++, tags, originalGeometry, projectedGeometry);
- if (result == null) { //don't bother processing further children
- return null;
- }
- out.addAll(result);
- }
-
- return out;
- }
-
- static abstract class Parser> extends JsonParser {
- protected final Class mapperClass = GenericMatcher.uncheckedFind(this.getClass(), Parser.class, "M");
-
- @Override
- public M read(JsonReader in) throws IOException {
- List children = readTypedList(in, this.mapperClass);
- checkState(!children.isEmpty(), "at least one member required!");
- return this.construct(children);
- }
-
- protected abstract M construct(@NonNull List children);
- }
-
- @JsonAdapter(Line.Parser.class)
- static class Line extends All implements LineMapper {
- public Line(LineMapper[] children) {
- super(children);
- }
-
- static class Parser extends All.Parser {
- @Override
- protected LineMapper construct(@NonNull List children) {
- return children.size() == 1 ? children.get(0) : new Line(children.toArray(new LineMapper[0]));
- }
- }
- }
-
- @JsonAdapter(Polygon.Parser.class)
- static class Polygon extends All implements PolygonMapper {
- public Polygon(PolygonMapper[] children) {
- super(children);
- }
-
- static class Parser extends All.Parser {
- @Override
- protected PolygonMapper construct(@NonNull List children) {
- return children.size() == 1 ? children.get(0) : new Polygon(children.toArray(new PolygonMapper[0]));
- }
- }
- }
-}
diff --git a/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/mapper/Any.java b/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/mapper/Any.java
deleted file mode 100644
index 8562d168..00000000
--- a/src/main/java/net/buildtheearth/terraplusplus/dataset/osm/mapper/Any.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package net.buildtheearth.terraplusplus.dataset.osm.mapper;
-
-import com.google.gson.annotations.JsonAdapter;
-import com.google.gson.stream.JsonReader;
-import lombok.AllArgsConstructor;
-import lombok.NonNull;
-import net.buildtheearth.terraplusplus.dataset.geojson.Geometry;
-import net.buildtheearth.terraplusplus.dataset.geojson.geometry.MultiLineString;
-import net.buildtheearth.terraplusplus.dataset.geojson.geometry.MultiPolygon;
-import net.buildtheearth.terraplusplus.dataset.osm.JsonParser;
-import net.buildtheearth.terraplusplus.dataset.osm.OSMMapper;
-import net.buildtheearth.terraplusplus.dataset.vector.geometry.VectorGeometry;
-import net.daporkchop.lib.common.util.GenericMatcher;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-import static net.daporkchop.lib.common.util.PValidation.*;
-
-/**
- * Returns the combined results of all of a number of mappers, ignoring any one of them that returns {@code null}.
- *
- * @author DaPorkchop_
- */
-@AllArgsConstructor
-abstract class Any> implements OSMMapper {
- @NonNull
- protected final M[] children;
-
- @Override
- public Collection apply(String id, @NonNull Map tags, @NonNull Geometry originalGeometry, @NonNull G projectedGeometry) {
- List out = new ArrayList<>();
- int i = 0;
- for (M child : this.children) {
- Collection result = child.apply(id + '/' + i++, tags, originalGeometry, projectedGeometry);
- if (result != null) { //don't bother processing further children
- out.addAll(result);
- }
- }
-
- return out;
- }
-
- static abstract class Parser> extends JsonParser {
- protected final Class mapperClass = GenericMatcher.uncheckedFind(this.getClass(), Parser.class, "M");
-
- @Override
- public M read(JsonReader in) throws IOException {
- List children = readTypedList(in, this.mapperClass);
- checkState(!children.isEmpty(), "at least one member required!");
- return this.construct(children);
- }
-
- protected abstract M construct(@NonNull List children);
- }
-
- @JsonAdapter(Line.Parser.class)
- static class Line extends Any implements LineMapper {
- public Line(LineMapper[] children) {
- super(children);
- }
-
- static class Parser extends Any.Parser {
- @Override
- protected LineMapper construct(@NonNull List children) {
- return children.size() == 1 ? children.get(0) : new Line(children.toArray(new LineMapper[0]));
- }
- }
- }
-
- @JsonAdapter(Polygon.Parser.class)
- static class Polygon extends Any implements PolygonMapper {
- public Polygon(PolygonMapper[] children) {
- super(children);
- }
-
- static class Parser extends Any.Parser