Git Product home page Git Product logo

georaster's People

Contributors

ajgrowney avatar aviklai avatar danieljdufour avatar elliots avatar jcphill avatar ragauskl avatar scazz010 avatar tommatheussen 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

georaster's Issues

noDataValue is not ignored to compute mins

Describe the bug

The value of noDataValue is not ignored to compute mins[0]

To Reproduce

The geotiff fetched from the urlToGeoTiff file has Int16 point values and -32768 should be considered as noDataValue.

// path /geotiff maps to directory resources/res/altimetria/tif/regions/
const urlToGeoTiff = `/geotiff/lisbon.tif`

fetch(urlToGeoTiff)
  .then(res => res.arrayBuffer())
  .then(arrayBuffer => {
    parseGeoraster(arrayBuffer, { noDataValue: -32768 }).then(georaster => {
     console.log(georaster.mins[0]) // `-32768`

Expected behavior
To compute mins or maxs by ignoring the points with value of noDataValue

Metadata values are ignored when loading COG from URL

Describe the bug
When loading a COG from URL, metadata values are not used. This might be intentional, but there is nothing in the documentation indicate that that's the case.

To Reproduce
Steps to reproduce the behavior:

  • Add break point in GeoRaster's constructor
  • Call parseGeoraster(https://path.to/cog.tiff, { projection: "example" })

Expected behavior
Metadata is expected to be used. When parseGeoraster's input is an ArrayBuffer, it is used.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: MacOS
  • Browser: Chrome
  • Version: 116

Additional context
I see that there are other types of inputs where metadata is not passed as well.

bilinear resample method is hard coded and not always a sensible option

Describe the bug

Hiya,

resampleMethod: 'bilinear',

Bilinear is usually a pretty good option for things like DTMs. But it doesn't work at all for things like land cover (e.g. where 10 means forest and 12 means water, it never makes sense to combine these to an 11, which may mean desert)

Expected behavior
Since the options object is passed directly to that function, an extra option that defaults to 'bilinear' is probably the most sensible way to solve this? According to the geotif docs 'nearest' is the only other (default) option. So, a different approach might be to follow the geotif library and make 'nearest' the default. Whilst not backward compatible, it might make understanding the library easier for new users. Nearest is also faster, so potentially a more sensible default for that reason too.


I'm about to fork and change this, so if you would like a PR, I can provide that

We had a chat a year or so ago, and I'm still using this library ;) Thanks again for the hard work!
S

Error Parsing deflate compressed geotiffs

Describe the bug
When attempting to load a deflate compressed tiff in geoblaze the following error is thrown:

Error: Geoblaze had a problem parsing this file. Please make sure that you are sending a proper GeoTIFF file and try again.

This was traced back to geoblaze dependency georaster:

When attempting to parse a geotiff with compression type deflate (32946) georaster throws the error:

Error: Unknown compression method identifier: 32946
at t.getDecoder (node_modules\georaster\dist\georaster.bundle.min.js:1:346511)

To Reproduce

Server side:
npm install georaster

run following code in any file

async function testGeoraster() {
    fs.readFile("./data/deflate.tiff", (error, data) => {
        parseGeoraster(data).then(georaster => {
            console.log('georaster: ',georaster)
        })
    }
    )
}

testGeoraster()

Expected behavior
Expected output is an object representing the data as an array buffer.

Desktop (please complete the following information):
Affects loading this type of tiff in node and browser

Additional context
you can download the same raster here and try load it at geotiff.io

A workaround to the issue was to fork georaster and geoblaze and generate new builds. However this is not optimal.

Can georaster please run a new build and release it on npm.

Parse NetCDF

Is your feature request related to a problem? Please describe.

People should be able to easily visualize and run basic analysis on a NetCDF file without having to download any software. Once NetCDF support is added to GeoRaster, we will update geoblaze and create netcdf.io

Describe the solution you'd like

Parse NetCDF files that follow Climate and Forecast Convention

Describe alternatives you've considered

N/A

Additional context

http://cfconventions.org/

maxs/mins/ranges calculation incorrect

The following code from processResult() has two problems:

  1. Because max and min are declared outside the line 18 rasterIndex loop and not reset, later rasters cannot have a higher min or lower max than earlier rasters.
  2. Because of the else on line 29, if the raster data is sorted from largest to smallest with no repeats then max is never assigned, and if the first element is the true maximum then the next-largest value will be reported instead.

let max; let min;
// console.log("starting to get min, max and ranges");
for (let rasterIndex = 0; rasterIndex < result.numberOfRasters; rasterIndex++) {
const rows = result.values[rasterIndex];
if (debug) console.log('[georaster] rows:', rows);
for (let rowIndex = 0; rowIndex < height; rowIndex++) {
const row = rows[rowIndex];
for (let columnIndex = 0; columnIndex < width; columnIndex++) {
const value = row[columnIndex];
if (value != noDataValue && !isNaN(value)) {
if (typeof min === 'undefined' || value < min) min = value;
else if (typeof max === 'undefined' || value > max) max = value;
}
}
}
result.maxs.push(max);
result.mins.push(min);
result.ranges.push(max - min);
}

For a test case, parseGeoraster([ [ [3, -3] ], [ [2, -2] ], [ [1, -1] ] ], metadata)
will calculate maxs: [undefined, 2, 2], mins: [-3, -3, -3], ranges: [NaN, 5, 5]

Support Zipped TIFF Files

Is your feature request related to a problem? Please describe.

Users sometimes have GeoTIFFs in zipped tiff file. For example, a file name could be something like ndvi.tif.zip

Describe the solution you'd like

Users should be able to be able to pass a (array)buffer of the zipped file to georaster, just as they can pass a buffer of an unzipped GeoTIFF. There may be a way to identify whether an buffer represents a zip file by looking for a magic number (i.e. byte identifier). There appears to be a few packages on NPM that do this. Therefore, the user won't have to specify the file type. They can just directly pass in a buffer and that's it.

Describe alternatives you've considered

None at the moment

Additional context

Basically, GeoTIFFs can get large and so people zip compress them. When people use mobile devices, it can be especially annoying and difficult to unzip tiff files. We want people to be able to use geotiff.io on mobile devices with .tiff.zip files.

ReferenceError: global is not defined when importing the library on client-side

Description:
ReferenceError: global is not defined when importing the library on client-side.

To Reproduce
When I try to import the library on a client-side project, I get the above error.
It looks like the library is trying to import node-fetch on a client-side environment.

In index.js - the line:
import nodeFetch from 'node-fetch';
imports node-fetch in any environment.

Expected behavior
The library should work on the client-side as well.

Screenshots
image

Desktop:

  • OS: Windows 10
  • Browser: Chrome
  • Version 78

Maybe it's possible to use isomorphic-fetch or cross-fetch?

Parse Georaster back to ArrayBuffer

In my application I am substracting 2 Geotiffs (values) to create a difference raster. To be able to plot this difference raster on my map using Geotiff.js, I need to pasre the whole Georaster object to an array buffer.

Is this possible or should I take a different route?

Support JPEG Files

Is your feature request related to a problem? Please describe.

Want to parse JPEG files

Describe the solution you'd like

Parse JPEG files. pixelWidth should probably just be 1 as in 1 unit or undefined unless geocoordinates specified

Describe alternatives you've considered

None

Additional context

Work on Node

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: [e.g. iOS]
  • Browser [e.g. chrome, safari]
  • Version [e.g. 22]

Smartphone (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]
  • Browser [e.g. stock browser, safari]
  • Version [e.g. 22]

Additional context
Add any other context about the problem here.

Get wkt

For ogc wkt, easily copy it

For esriwkt, idk.. gzip compress ESRI wkt database or put it in a .dat?

Auto-calculate bounds

If a user passes in pixelWidth and xmax, we should automatically calculate xmin.

Same with y values.

Support passing HTTP headers to the GeoTiff request

Is your feature request related to a problem? Please describe.

I have COGs that I need a Bearer token to via a HTTP header.

Describe the solution you'd like

I'd like to be able to pass options to the HTTP request. This should be possible to provide to the fromUrl(s) methods of geotiff.js.
OpenLayers also does it and could be used as a reference.

Additional context
Code: https://github.com/GeoTIFF/georaster/blob/master/src/index.js#L94

Related issues:

Is it possible to combine the values from two rasters? I.e. raster math client side

Is your feature request related to a problem? Please describe.
This feature request is not related to a problem.

Describe the solution you'd like
We would like to be able to perform things like image differencing client side - subtracting the pixel values of one raster from another, and displaying the results.

Describe alternatives you've considered
We have tried implementing the server side.

Additional context
We are also using georaster-layer-for-leaflet, and are very grateful for this awesome project.

Broken dependency on geotiff.js

When using [email protected] to install dependencies of our app that depends on geoblaze@^0.1.8, we get an error:

warning Pattern ["geotiff@github:danieljdufour/geotiff.js#877f064"] is trying to unpack in the same destination "/w/workspace/imagery_ui-merge-master-none/.yarn_cache/v2/npm-geotiff-0.4.1" as pattern ["geotiff@^0.4.1"]. This could result in non-deterministic behavior, skipping.
error https://codeload.github.com/danieljdufour/geotiff.js/tar.gz/877f064846d6446da1d30f727ee144ffa590ea77: Integrity check failed for "geotiff" (computed integrity doesn't match our records, got "sha1-a7VkDR5y+0Xn3cKyqsSqKtfSCXU=")

We traced the root cause to georaster (hence creating this issue). Here is the dependency subtree

[email protected]
| _ [email protected]
    |_ geotiff@github:danieljdufour/geotiff.js#877f064
|_ [email protected],

As you can see geotiff@github:danieljdufour/geotiff.js#877f064 conflicts with [email protected] because both of them are versioned as 0.4.1 in their respective package.json file.

Can georaster stop using geotiff@github:danieljdufour/geotiff.js#877f064 and replace it with the latest version geotiff (i.e. [email protected])?

Save as PNG

Is your feature request related to a problem? Please describe.

Sometimes users might want to save their GeoRaster as a PNG file. For example, this would be useful for displaying results in Observable or Jupyter Notebooks.

Describe the solution you'd like

We should create a new function called savePNG that returns an (array)buffer for a PNG.

Describe alternatives you've considered

I've thought about creating a save method where you pass in the filename and the function auto-detects the file type from the extension of the filename. I don't think this would be a good idea, because we can't easily save files in the browser and I think this would make this package much more complicated. Perhaps, we can explore this after creating the function that creates the arraybuffer because I think this is a pre-requisite to saving a file, anyway.

Additional context

Should users have to manually create a data URI like those found at https://en.wikipedia.org/wiki/Data_URI_scheme or should we have a separate method savePNGDataURI. It might be more maintainable to force the users to construct their own data URIs, but I'm not sure what % of users will know how to do this.

rasterio-generated geotiffs have wrong metadata

Describe the bug
A clear and concise description of what the bug is.
When opening a rasterio-generated geotiff with georaster, I get the wrong ymin and ymax, and likely other metadata. This is likely because rasterio has an opposite standard to GDAL/QGIS with respect to the grid ordering..

As a result of this, using georaster-for-leaflet, the map is subsequently displayed upside down. It is properly displayed in QGIS.

To Reproduce
Steps to reproduce the behavior:

  1. Create a geotiff with rasterio/rioxarray
  2. Open said geotiff with georaster
  3. See erroneous metadata
  4. When opening with georaster for leaflet, the raster is displayed upside down.

Upside down (from rioxarray):
image

Correct display (re-exported with QGIS):
image

Latest release broke my implementation for COG

With small geotiffs (<1000x1000), the latest release causes an error

Error: No image at index 4

With large geotiffs (5000x5000+) this is not a problem. I have fixed it by relying on version 1.0.0. The no image at index issue is altered by the pyramiding for the COG.

In GDAL, pyramiding a TIF with:

!gdaladdo -r average -ro ../data.tif 2 4 8 16

will cause a No image at index 4 error, while pyramiding with:

!gdaladdo -r average -ro ../data.tif 2 4 8 16 32

will cause a No image at index 5 error

I am using georaster-layer-for-leaflet to display COGs on a leaflet webmap. My COG is loaded like so:

var url_to_geotiff_file = "https://bucket.storage.googleapis.com/" + variable + ".tif";

        parseGeoraster(url_to_geotiff_file).then(georaster => {
          var layer = new GeoRasterLayer({
              attribution: "",
              georaster: georaster,
              resolution: 768,
              pixelValuesToColorFn: values => values[0] >= 0.33 ? "#6cbe76" : null,
          });

Extract GeoTIFF metadata/tags in parseData

Is your feature request related to a problem? Please describe.

I am using code like this to construct Leaflet layers from GeoTIFF files:

    fetch(url)
      .then(response => response.arrayBuffer())
      .then(arrayBuffer => {
        parseGeoraster(arrayBuffer).then(georaster => {
          var layer = rasterToLayer(georaster);  // creates a GeoRasterLayer with color mapping
          layerControl.addOverlay(layer, name);
      });
    });

This works well. However, in addition to the raster data itself, I now want to access the metadata/tag key-value pairs embedded within GeoTIFF files. As far as I can tell, there is no way to access that information from the georaster object returned by parseGeoraster, except by re-parsing the original array buffer using geotiff.js. I'd rather not do that, to keep my code simpler and more efficient. It would be nice if I could just access it from what parseGeoraster returns instead.

Describe the solution you'd like
Add a call to image.getGDALMetadata() somewhere in here: https://github.com/GeoTIFF/georaster/blob/master/src/parseData.js#L65

getGDALMetadata returns exactly the metadata I am trying to access, so I propose calling it and storing the value as a new field on parseData's result object.

I think the new field would then propagate out and be included in the object returned from parseGeoraster.

Describe alternatives you've considered
I suppose instead of storing the results of image.getGDALMetadata(), the image itself could be stored, which might be more generally useful (all of its methods would then be available, instead of just getGDALMetadata).

Additional context
In case I'm not using the correct terminology (I am new to GeoTIFFs), the key-value pairs I am talking about are shown in the Metadata section of gdalinfo's output. Here's an example, where I want to access the CREATION_DATE, AUTHOR etc fields:

$ gdalinfo example.tiff 
Driver: GTiff/GeoTIFF
Files: example.tiff
Size is 115, 48
Coordinate System is:
GEOGCRS["WGS 84",
    DATUM["World Geodetic System 1984",
        ELLIPSOID["WGS 84",6378137,298.257223563,
            LENGTHUNIT["metre",1]]],
    PRIMEM["Greenwich",0,
        ANGLEUNIT["degree",0.0174532925199433]],
    CS[ellipsoidal,2],
        AXIS["geodetic latitude (Lat)",north,
            ORDER[1],
            ANGLEUNIT["degree",0.0174532925199433]],
        AXIS["geodetic longitude (Lon)",east,
            ORDER[2],
            ANGLEUNIT["degree",0.0174532925199433]],
    USAGE[
        SCOPE["unknown"],
        AREA["World"],
        BBOX[-90,-180,90,180]],
    ID["EPSG",4326]]
Data axis to CRS axis mapping: 2,1
Origin = (-124.750000000000000,48.250000000000000)
Pixel Size = (0.500000000000000,-0.500000000000000)
Metadata:
  AREA_OR_POINT=Area
  CREATION_DATE=2023-12-21
  DESCRIPTION=A raster file representing some nifty geospatial dataset.
  AUTHOR=Abraham Lincoln
Image Structure Metadata:
  INTERLEAVE=BAND
Corner Coordinates:
Upper Left  (-124.7500000,  48.2500000) (124d45' 0.00"W, 48d15' 0.00"N)
Lower Left  (-124.7500000,  24.2500000) (124d45' 0.00"W, 24d15' 0.00"N)
Upper Right ( -67.2500000,  48.2500000) ( 67d15' 0.00"W, 48d15' 0.00"N)
Lower Right ( -67.2500000,  24.2500000) ( 67d15' 0.00"W, 24d15' 0.00"N)
Center      ( -96.0000000,  36.2500000) ( 96d 0' 0.00"W, 36d15' 0.00"N)
Band 1 Block=115x17 Type=Float32, ColorInterp=Gray
  NoData Value=-9999

add toCanvas method

Is your feature request related to a problem? Please describe.

no easy way to display raster image on ObservableHQ.com

Describe the solution you'd like

toCanvas(height, width) method

Describe alternatives you've considered

toPNG or toJPG

Additional context

Read PNG's

Is your feature request related to a problem? Please describe.

Users might want to read satellite images stored as PNG's

Describe the solution you'd like

Add PNG support to GeoRaster

Describe alternatives you've considered

None

Additional context

Missing Tiles on COG edges where tile includes transparency

Issue
Error in Leaflet using georaster-layer-for-leaflet - SOI not found.

In Node with v 2.0.7+ using geotiff directly - Cannot read properties of undefined (reading 'offset').

Use this raster as [long as it's hosted] inside georaster-layer-for-leaflet:
https://tilestream-cogs.nyc3.digitaloceanspaces.com/OSU_Main_Campus_COG.tif

Expected behavior
Receive an image tile - OpenLayers somehow handles these errors and is able to still return a valid tile, using geotiff version 2.0.7, but in geotiff.js in other applications such as this and in my own testing I cannot get past the errors in the getTileOrStrip code using the same version.

Desktop and Node

The issue cannot be with the geotiff library directly as OL works using the same codebase.

Leaflet

image image

OpenLayers

image

parseGeoraster: catching error

Hey guys, I'd like to know how to catch error when parsing the raster.
Let assume I have the following code:

reader.readAsArrayBuffer(file);
 reader.onloadend = function() {
    var arrayBuffer = reader.result;
    parseGeoraster(arrayBuffer).then(georaster => {
        console.log(georaster);
    })
     .catch(e => {console.log("got ya")})
};

I expect the "got ya" message (for ex) if the file doesnt have coordinates system but I could not catch the error. Any help will be very welcome :)

Unhandled promise rejection

Describe the bug
Error is not catched withing the package, therefore it keep initial method, where it was called, hanging. Console log 'UnhandledPromiseRejectionWarning:' as in 2 examples below:

(node:26504) UnhandledPromiseRejectionWarning: TypeError: Invalid byte order value. at Function.<anonymous> (C:\Users\ragau\Desktop\testing\tiff-server\node_modules\georaster\dist\georaster.bundle.min.js:8:454885)

(node:26504) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'GeographicTypeGeoKey' of null at C:\Users\ragau\Desktop\testing\tiff-server\node_modules\georaster\dist\georaster.bundle.min.js:8:443308

To Reproduce
Steps to reproduce the behaviour:

  1. Try to parse a file buffer of an image that does not have geo data

Expected behavior
A error should be thrown/returned in a way where it can be caught by calling method

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: Win10
  • Environment: Node
  • Version 0.5.2

Support for DataView

It would be nice if DataView was supported for parsing, as for now only ArrayBuffer is and a view onto it is not.
Right now if multiple data are stored into a single ArrayBuffer the only way for the parser to work is to copy the interesting part into a new ArrayBuffer, copy which could be avoided.
Thank you !

Load from Blob on front-end

Is your feature request related to a problem? Please describe.
I want to display a large GeoTIFF file on the front-end filesystem via a File (Blob) object instead of an ArrayBuffer.

Describe the solution you'd like
geotiff exports a fromBlob function similar to the fromUrl and fromArrayBuffer functions currently in use.
The GeoRaster constructor should detect if a Blob is passed in and call fromBlob instead of fromUrl, and likely the "if (this._url) ..." code paths will need to be taken for Blob data as well. The Blob should be assumed to be very large and only loaded into memory as needed (as with a cloud optimized GeoTIFF loaded from a URL).

Describe alternatives you've considered
Using createObjectURL to create a URL string from the File object and passing the URL to parseGeoraster works on Chrome but fails on Firefox due to a bug in geotiff (geotiffjs/geotiff.js#207). It also seems that using fromBlob would be more efficient than fetch calls to an object URL.

Additional context
Loading large files from an ArrayBuffer uses lots of memory and takes several minutes to display. Loading from an object URL as described above displays almost instantly.

Render to a specific zoom/pyramid level?

Is your feature request related to a problem? Please describe.
Not a problem.

Describe the solution you'd like
When i call parseGeoraster() i would like to be able to specify which "pyramid level" i want to be rendered initially.

Describe alternatives you've considered
Nothing.

Additional context
It might be possible already - but i have not been able to figure out if it is.

parseGeoraster .ovr detection

Hi,

Great package! I'm using this along with georaster-layer-for-leaflet to overlay cloud optimized geotiffs on a leaflet map.

Going off of the various examples here https://github.com/GeoTIFF/georaster, when I use the "load from url on front-end"/arraybuffer example, it works fine. However, when I use the "load cloud optimized geotiff" example where no arraybuffer is used, I get a HEAD 403 error from the parseGeoraster function - it seems to be looking for a .ovr file that doesn't exist. My files have internal overviews and thus no .ovr files should exist, but the parseGeoraster function seems to automatically look for a .ovr file and throws an error if not found..

I see in the description for this method - "It will also attempt to automatically discover any available overview files." Will this method work with cog's with internal overviews vs external? Is there a way I can bypass this error or an option I can provide to specify that my files use internal overviews? I'd much prefer to avoid loading the whole file via the arraybuffer route for speed/efficiency purposes i.e. one of the main benefits of a cog.

Thanks much for any insight!

Best,
S

webpack 5 support

Describe the bug
When installing in a project that uses webpack 5 (e.g. STAC Browser), I'm getting the following error when running npm install:

 Could not resolve dependency:
npm WARN peer webpack@"^3.0.0 || ^4.0.0-alpha.0 || ^4.0.0" from [email protected]
npm WARN node_modules/worker-loader
npm WARN   worker-loader@"^2.0.0" from [email protected]
npm WARN   node_modules/georaster
npm WARN
npm WARN Conflicting peer dependency: [email protected]
npm WARN node_modules/webpack
npm WARN   peer webpack@"^3.0.0 || ^4.0.0-alpha.0 || ^4.0.0" from [email protected]
npm WARN   node_modules/worker-loader
npm WARN     worker-loader@"^2.0.0" from [email protected]
npm WARN     node_modules/georaster

Expected behavior
Could we allow webpack 5, too?

WebWorker Out Of Date?

Looks like your WebWorker script is referencing _arrayBuffer here, instead of _data.

I actually haven't got anything working yet, but thought I'd point that out in case you want to take a look at it.

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.