Giter VIP home page Giter VIP logo

geojson-jackson's Introduction

GeoJson POJOs for Jackson

A small package of all GeoJson POJOs (Plain Old Java Objects) for serializing and deserializing of objects via JSON Jackson Parser. This libary conforms to the 2008 GeoJSON specification.

Usage

If you know what kind of object you expect from a GeoJson file you can directly read it like this:

FeatureCollection featureCollection = 
	new ObjectMapper().readValue(inputStream, FeatureCollection.class);

If you want to read any GeoJson file read the value as GeoJsonObject and then test for the contents via instanceOf:

GeoJsonObject object = new ObjectMapper().readValue(inputStream, GeoJsonObject.class);
if (object instanceof Polygon) {
	...
} else if (object instanceof Feature) {
	...
}

and so on.

Or you can use the GeoJsonObjectVisitor to visit the right method:

GeoJsonObject object = new ObjectMapper().readValue(inputStream, GeoJsonObject.class);
object.accept(visitor);

Writing Json is even easier. You just have to create the GeoJson objects and pass them to the Jackson ObjectMapper.

FeatureCollection featureCollection = new FeatureCollection();
featureCollection.add(new Feature());

String json= new ObjectMapper().writeValueAsString(featureCollection);

Maven Central

You can find the library in the Maven Central Repository.

<dependency>
 <groupId>de.grundid.opendatalab</groupId>
 <artifactId>geojson-jackson</artifactId>
 <version>1.14</version>
</dependency>

geojson-jackson's People

Contributors

babbleshack avatar dependabot[bot] avatar gotusso avatar grundid avatar lucassaldanha avatar notanyron avatar pigelvy avatar robpc avatar trygveaa avatar twillouer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

geojson-jackson's Issues

Classes implementing Serializable should set a serialVersionUID

About Crs and LngLatAlt, SonarQube has a rule that tells me the following:

Missing Serial Version UID
Classes that are serializable should provide a serialVersionUID field

For further details on the purpose of serialVersionUID, please have a look at this StackOverflow question.

thx

1.2 Release

When do you intend on releasing 1.2? I need the 1.6 compiled version :)

How to get polygon.getPoints() from Featurecollection

Secene: I read json file by geojson-jackson plugin and require to get each polygon's points(List).
Trouble: I don't know how to translate from fea.getGeometry() to points(List).

Code Error:
ObjectMapper mapper = new ObjectMapper();
try{
File jsonfile=new File(jsonPath);//my json file
Data data=mapper.readValue(new File(jsonPath), Data.class);
FeatureCollection fc=geojsonlist.get(i).getValue();
List fealist=fc.getFeatures();
for(int j=0;j<fealist.size();j++){
Feature fea=fealist.get(i);
Polygon polygon=fea.getGeometry().; -------------Code Error(I need get each polygon or polyline 's List / coordinates)

Incompatible with ParameterNamesModule

Deserialization of Polygon fails when the ParameterNamesModule is enabled with the properties creator binding mode:
objectMapper.registerModule(new ParameterNamesModule(JsonCreator.Mode.PROPERTIES))

Implement `calculateBoundingBox()` method for `GeoJsonObject`s.

Add a calculateBoundingBox() method to GeoJsonObject, which would calculate (and reset) the object's bbox based on the instance's other attributes.

Class Suggested Implementation
GeoJsonObject Define it as abstract to force implementation classes to provide it.
Feature Call this.getGeometry().calculateBoundingBox().
FeatureCollection Get the box for each Feature in the collection, then draw a box around all results.
Geometry Leave it abstract.
LineString Might get away with using MultiPoint's implementation?
MultiLineString Calculate min/max lat/long among all line endpoints.
MultiPoint Calculate the min/max lat/long from all points.
MultiPolygon Get the box for each Polygon, then draw a box around all of those boxes.
Point Set a "box" at the point's coordinates.
Polygon Calculate the min/max lat/long from all points on the outermost ring.

The order of the four double values must correspond to the order assumed in the definition of the bbox member of GeoJsonObject (whatever that is).

Consider calling this method automatically in any method that alters the shape of the object, such that the bounding box is updated in real time.

Feature geometry should be constrained to Geometry type

Currently Feature.java has a private GeoJsonObject geometry;. This type should instead be private Geometry geometry; per section 3.2 of the geojson spec:

A Feature object has a member with the name "geometry". The value of the geometry member SHALL be either a Geometry object as defined above or, in the case that the Feature is unlocated, a JSON null value.

Serialization of List<Feature> does not include type

Serialization of feature lists should include the feature type. We are forced to use a FeatureCollection to the type be included in the serialization.

List<Feature> features = new ArrayList<>();
features.add(new Feature());
String json = new ObjectMapper().writeValueAsString(features);
System.out.println(json);
// output: [{"properties":{},"geometry":null}]

geojson-jackson does not work when AUTO_DETECT_GETTERS is set to false

When I try to use geojson-jackson it doesn't de serialize coordinates from point (for example when the default mapper feature AUTO_DETECT_GETTERS is set to false.

Is it possible to make geojson-jackson such that it also works when the this mapper setting is put diffrent then the default?

Best regards

Java 1.6 support

Hi, I needed Java 1.6 support on this project so I made a fork for it. The changes are quite minimal. Do you think that may be useful? Should I make a pull request?

Potential fail of LngLatAlt#equals(Object) since lon/lat values are rounded during serialization

Double to String conversion in LngLatAlt serializer breaks LngLatAlt#equals(Object) method due to rounded values. Please, take into account the following test where a new point is created from real longitude and latitude values, converted into JSON and read again into a Point object:

package example;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.geojson.Point;

import static org.apache.commons.lang3.StringUtils.trim;
import static org.junit.Assert.fail;
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;

public class JsonTest {
    @Test
    public void test() {
        try {
            Point point = new Point(-0.3762881000000107d, 39.4699075d);
            assertThat("original point is not null", point, notNullValue());

            ObjectMapper mapper = new ObjectMapper();
            assertThat("mapper is not null", mapper, notNullValue());

            String payload = mapper.writeValueAsString(point);
            assertThat("JSON is not empty", trim(payload), allOf(notNullValue(), not(equalTo(""))));

            Point point2 = mapper.readValue(payload, Point.class);
            assertThat("new point is not null", point2, notNullValue());

            assertThat("new point coincides with original", point2, equalTo(point));
        } catch (Exception e) {
            e.printStackTrace(System.err);
            fail("Test failed: " + e.getMessage());
        }
    }
}

The error message:

java.lang.AssertionError: new point coincides with original
Expected: <Point{coordinates=LngLatAlt{longitude=-0.3762881000000107, latitude=39.4699075, altitude=NaN}} GeoJsonObject{}>
     but: was <Point{coordinates=LngLatAlt{longitude=-0.3762881, latitude=39.4699075, altitude=NaN}} GeoJsonObject{}>
        at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
        at example.JsonTest.test(JsonTest.java:32)

Serialization of attribute "properties"

The GeoJson that is produced by geojson-jackson in combination with my mapper (a plain old MAPPER without any special configuration) does not seem to be valid geojson (according to geojsonlint.com and the GeoJSON specification).

The reason is that the properties field is not added to Features if there are no properties. According to the specification this is not valid. From http://geojson.org/geojson-spec.html: "The value of the properties member is an object (any JSON object or a JSON null value)."

It is valid to pass an empty object or a null value. To get the created string value validated, I had to add a mixin to my mapper that includes the following code:

abstract class FeatureMixIn {
    @JsonInclude(Include.ALWAYS)
    public abstract Map<String, Object> getProperties();
}

However, this adds an empty object and not a null value. In fact I'd expect "null" and not an empty object, but since this behavior is valid GeoJSON that's OK for me.

Shouldn't the @JsonInclude(Include.NON_EMPTY) in the GeoJsonObject class be changed to ALWAYS for the Feature subclass (any maybe for other subclasses as well... I did not check this)??

Maybe this should also be done for the geometry type as well, since the GeoJSON specification also states that this field has to exist for valid GeoJSON.

Can not construct instance of org.geojson.GeoJsonObject

Cannot parse a valid GeoJSON string via readValue(geoJson, GeoJsonObject.class);.

Here is the code to reproduce the exception:

String geoJson = "{\"type\":\"FeatureCollection\",\"features\":[{\"type\":\"Feature\",\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[-126.456789,-2.123,0.0],[-123.456789,2.123,0.0],[-124.456789,2.123,0.0],[-125.456789,-2.123,0.0],[-126.456789,-2.123,0.0]]]},\"properties\":{\"myProp\":\"PropData1\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[-123.123,55.555,0.0]},\"properties\":{\"myProp\":\"PropData2\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[123.456789,2.123,0.0],[-123.456789,2.123,0.0],[-124.456789,2.123,0.0],[-125.456789,-2.123,0.0],[123.456789,2.123,0.0]]]},\"properties\":{\"myProp\":\"PropData3\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[-15.123,75.555,0.0]},\"properties\":{\"myProp\":\"PropData4\"}}]}";

GeoJsonObject object = new ObjectMapper().readValue(geoJson, GeoJsonObject.class);

The log is the next:

Can not construct instance of org.geojson.GeoJsonObject, problem: abstract types can only be instantiated with additional type information
 at [Source: java.io.StringReader@aa0657b; line: 1, column: 1]
org.codehaus.jackson.map.JsonMappingException: Can not construct instance of org.geojson.GeoJsonObject, problem: abstract types can only be instantiated with additional type information
 at [Source: java.io.StringReader@aa0657b; line: 1, column: 1]
	at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:163)
	at org.codehaus.jackson.map.deser.StdDeserializationContext.instantiationException(StdDeserializationContext.java:233)
	at org.codehaus.jackson.map.deser.AbstractDeserializer.deserialize(AbstractDeserializer.java:60)
	at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:2732)
	at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1863)

For convince here is the geoJson which I try to parse:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              -126.456789,
              -2.123,
              0.0
            ],
            [
              -123.456789,
              2.123,
              0.0
            ],
            [
              -124.456789,
              2.123,
              0.0
            ],
            [
              -125.456789,
              -2.123,
              0.0
            ],
            [
              -126.456789,
              -2.123,
              0.0
            ]
          ]
        ]
      },
      "properties": {
        "myProp": "PropData1"
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          -123.123,
          55.555,
          0.0
        ]
      },
      "properties": {
        "myProp": "PropData2"
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              123.456789,
              2.123,
              0.0
            ],
            [
              -123.456789,
              2.123,
              0.0
            ],
            [
              -124.456789,
              2.123,
              0.0
            ],
            [
              -125.456789,
              -2.123,
              0.0
            ],
            [
              123.456789,
              2.123,
              0.0
            ]
          ]
        ]
      },
      "properties": {
        "myProp": "PropData3"
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          -15.123,
          75.555,
          0.0
        ]
      },
      "properties": {
        "myProp": "PropData4"
      }
    }
  ]
}

conversion to JTS geometry

is there a straightforward way to convert between a JTS shape and your GeoJSON shape back and forth?

apologies if I missed it.

Only name Crs

The current implementation only allow to Create name Crs while the specification also allow for the creation of linked CRS.

Is it possible to create such ?

Add support for a foreign Member

When trying to add Parameters to hold some metadata on the geojson, I was unable to find a method for adding a foreign member.

Is this something that can be added?

README typo.

README file typo:
instanceOf should be instanceof

GeoJsonObject object = new ObjectMapper().readValue(inputStream, GeoJsonObject.class);
if (object instanceOf Polygon) {
...
} else if (object instanceOf Feature) {
...
}

About how to use geojson-jackson to parse geojson

Hi there,

When I tried to use this lib to parse geojson data with the following code:

GeoJsonObject object = mapper.readValue(geometryJson, GeoJsonObject.class);
if (object instanceof Polygon) {
    Polygon  polygon = (Polygon) object; 
} else if (object instanceof LineString) {
    LineString lineString = (LineString) object;
}

I got this error:

[err] org.codehaus.jackson.map.JsonMappingException: Can not construct instance of org.codehaus.jackson.map.type.SimpleType, problem: abstract types can only be instantiated with additional type information
 at [Source: java.io.StringReader@13ed8e85; line: 1, column: 1]
[err]   at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:160)
[err]   at org.codehaus.jackson.map.deser.StdDeserializationContext.instantiationException(StdDeserializationContext.java:214)
[err]   at org.codehaus.jackson.map.deser.AbstractDeserializer.deserialize(AbstractDeserializer.java:44)
[err]   at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:1980)
[err]   at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1271)

Could you please show me the right way to use it?

Turning on the SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED and DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY of ObjectMapper breaks LngLatAlt deserialization

Software Versions:

  • Java: 17.0.11-amzn managed by sdkman
  • Jackson: 2.15.4
  • geojson-jackson: 1.14

Executive Summary

The LngLatAltSerializer and LngLatAltDeserializer cannot properly handle the SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED and DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY features being turned on in an ObjectMapper.

Details

Running the following code throws the below redacted exception. Substituting the Polygon with a similar MultiPolygon or MultiLineString should produce a similar exception.

ObjectMapper mapper = new ObjectMapper()
    .enable(SerializationFeature.INDENT_OUTPUT)
    .enable(SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED)
    .enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
Polygon polygon = new Polygon(List.of(
    new LngLatAlt(0.0, 0.0),
    new LngLatAlt(1.0, 0.0),
    new LngLatAlt(0.0, 1.0),
    new LngLatAlt(0.0, 0.0)
));
String str = mapper.writeValueAsString(polygon);
mapper.readValue(str, Polygon.class);
com.fasterxml.jackson.databind.JsonMappingException: Cannot deserialize instance of `org.geojson.LngLatAlt` out of VALUE_NUMBER_FLOAT token
 at [Source: (String)"{
  "type" : "Polygon",
  "coordinates" : [ [ 0.0, 0.0 ], [ 1.0, 0.0 ], [ 0.0, 1.0 ], [ 0.0, 0.0 ] ]
}"; line: 3, column: 23] (through reference chain: org.geojson.Polygon["coordinates"]-]java.util.ArrayList[0]-]java.util.ArrayList[0])
  at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:269)
  at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:2201)
  at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:2193)
  at org.geojson.jackson.LngLatAltDeserializer.deserialize(LngLatAltDeserializer.java:20)
  at org.geojson.jackson.LngLatAltDeserializer.deserialize(LngLatAltDeserializer.java:13)
  at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer._deserializeFromArray(CollectionDeserializer.java:359)
  at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:244)
  at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:28)
  at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer._deserializeFromArray(CollectionDeserializer.java:359)
  at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:244)
  at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:28)
  at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
  at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:314)
  at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:215)
  at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:187)
  at com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer._deserializeTypedForId(AsPropertyTypeDeserializer.java:170)
  at com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer.deserializeTypedFromObject(AsPropertyTypeDeserializer.java:136)
  at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeWithType(BeanDeserializerBase.java:1306)
  at com.fasterxml.jackson.databind.deser.impl.TypeWrappedDeserializer.deserialize(TypeWrappedDeserializer.java:74)
  at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:323)
  at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4825)
  at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3772)
  at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3740)
  at ██████████(██████████.java:██████████)
  at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
  at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

I believe the issue stems from the following two json Strings that are produced and then interpreted by mapper.readValue(str, Polygon.class) when SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED is turned on or off, respectively. The former throws the exception while the latter does not, due to expecting the 3rd set of array brackets. When the feature is turned on, the outermost brackets are not written since they are "unwrapped" by the feature. Thus, in the former scenario, jackson "opens" both arrays since it knows from the type that there are 2 outer list/array types and tries to pass the 1st DoubleNode to the LngLatAltDeserializer, which expects the [ token instead.

{
  "type" : "Polygon",
  "coordinates" : [ [ 0.0, 0.0 ], [ 1.0, 0.0 ], [ 0.0, 1.0 ], [ 0.0, 0.0 ] ]
}
{
  "type" : "Polygon",
  "coordinates" : [ [ [ 0.0, 0.0 ], [ 1.0, 0.0 ], [ 0.0, 1.0 ], [ 0.0, 0.0 ] ] ]
}

Potential Solutions

  1. Use annotations to turn off the SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED and DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY features for only the geojson classes so that said features can still be turned on for the surrounding json document without breaking serialization/deserialization of the geojson. This might be the prefered solution since RFC7946 does not yet appear to have any examples of "unwrapped single element arrays".
  2. Perhaps there is a way to indicate to the jackson library that LngLatAlt objects should be treated like an array when serializing/deserializing them so it properly generates the 3rd wrapping ArrayNode even when the above features are turned on? Maybe either making LngLatAlt extend List or having the LngLatAltDeserializer advertise that it produces an array by overriding the hangleType() function to return List.class or logicalType() to return LogicalType.Array?

How to configure unknown fields to be ignorable?

It seems that the data provider I am using respond with invalid GeoJSON.
https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_day.geojson

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "metadata" (class org.geojson.FeatureCollection), not marked as ignorable (3 known properties: "bbox", "crs", "features"])
 at [Source: https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_day.geojson; line: 1, column: 41] (through reference chain: org.geojson.FeatureCollection["metadata"])

How can I configure unknown fields to be ignorable?

Kind regards,
Daniel

Make parsing of `crs` more lenient

At present, type property of crs is mapped to org.geojson.jackson.CrsType enum. This makes it challenging to parse GeoJSON containing crs.type value outside of those outlined by the spec (and present in the enum).

One such example is government WFS service that provides cadastral data here in Croatia. The crs property of GeoJSON returned by this service contains the following:

"crs": {
    "type": "EPSG",
    "properties": {
        "code": "3765"
    }
}

Attempting to parse such GeoJSON using something like:

JsonMapper.builder().build().readValue("""
        {
            "type": "FeatureCollection",
            "totalFeatures": 0,
            "features": [],
            "crs": {
                "type": "EPSG",
                "properties": {
                    "code": "3765"
                }
            }
        }
        """, FeatureCollection.class);

Fails with InvalidFormatException:

Cannot deserialize value of type `org.geojson.jackson.CrsType` from String "EPSG": not one of the values accepted for Enum class: [link, name]

Additionally, GeoJSON spec linked in introduction is obsoleted by RFC 7946 which actually removes crs from the spec. See Appendix B of the RFC:

Appendix B.  Changes from the Pre-IETF GeoJSON Format Specification

   This appendix briefly summarizes non-editorial changes from the 2008
   specification [GJ2008].

B.1.  Normative Changes

   o  Specification of coordinate reference systems has been removed,
      i.e., the "crs" member of [GJ2008] is no longer used.

All of this IMO supports the case for a more lenient parsing of crs in geojson-jackson.

Conversion from double to string

After saving a Point into MongoDB I realized it converts double to String

As I know... GeoJSON specify numbers inside the array coordinates. Am I wrong?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.