matanyadaev / laravel-eloquent-spatial Goto Github PK
View Code? Open in Web Editor NEWLaravel Eloquent spatial package.
License: MIT License
Laravel Eloquent spatial package.
License: MIT License
The composer.json
of this package still tries to auto-discover a service provider, but there isn't one.
Proposed solution: remove the auto-discovery line from the composer.json
:
laravel-eloquent-spatial/composer.json
Lines 50 to 55 in c7098c0
It would be great if you could create a new release (v1.0.4) from the current master that includes the changes related to phpstan
Hey there,
so i am currently working on a Project that needs Points for a Location and we are sending over the Data as an array.
Right now i am trying to get a helper function to work, but it seems it only works with create()
and everything else like update()
, updateOrCreate()
, doesnt seem to work at all.
/**
* Create or update event location
* Converts latitude/longitude to SpatialPoint.
*/
public function setLocation(array $data): void
{
$location = Arr::map($data, function ($value, $key) {
if (str_contains($key, 'coordinates')) {
$value = new Point($value['latitude'], $value['longitude']);
}
return $value;
});
$this->location()->updateOrCreate($location);
}
Error that i am getting back is (note this is from postman):
"Object of class MatanYadaev\\EloquentSpatial\\Objects\\Point could not be converted to string"
For the setup
location is just casting two attributes (exact_coordinates and fuzzy_coordinates, which are always given from the post request) into a Point::class
.
Edit: Using laravel-eloquent-spatial 2.0
Hi, I just started using your package yesterday, so i may not understand something (do not blame me to hard =D).
I found that creating a new instance of MatanYadaev\EloquentSpatial\Objects\Point
(or other spatial abstractions as well) is a bit of a mess (if your project big enough and you have a ton of spatial data manipulations).
Wouldn't it be nice to have string values support for creating models with spatial data types?
For example this code from your readme:
$vaticanCity = Place::create([
'name' => 'Vatican City',
'area' => new Polygon([
new LineString([
new Point(12.455363273620605, 41.90746728266806),
new Point(12.450309991836548, 41.906636872349075),
new Point(12.445632219314575, 41.90197359839437),
new Point(12.447413206100464, 41.90027269624499),
new Point(12.457906007766724, 41.90000118654431),
new Point(12.458517551422117, 41.90281205461268),
new Point(12.457584142684937, 41.903107507989986),
new Point(12.457734346389769, 41.905918239316286),
new Point(12.45572805404663, 41.90637337450963),
new Point(12.455363273620605, 41.90746728266806),
]),
]),
])
Could be rewritten as such:
$vaticanCity = Place::create([
'name' => 'Vatican City',
'area' => new Polygon([
new LineString([
'12.455363273620605,41.90746728266806',
'12.450309991836548,41.906636872349075',
'12.445632219314575,41.90197359839437',
'12.447413206100464,41.90027269624499',
'12.457906007766724,41.90000118654431',
'12.458517551422117,41.90281205461268',
'12.457584142684937,41.903107507989986',
'12.457734346389769,41.905918239316286',
'12.45572805404663,41.90637337450963',
'12.455363273620605,41.90746728266806',
]),
]),
])
Is it possible and what do you think about that?
Currently the library just supports Laravel 8. Will it be updated to support Laravel 9?
I'm getting a casting problem when running this update:
I have a Point
value set from request properties like this:
$return_location = new Point((float)$request->latitude, (float)$request->longitude);
This is then used to update DB records:
$count = Checkout::query()
->where('user_id', $user->id)
->limit(1)
->update(
[
'return_location' => $return_location,
]
);
but even though the Point object is valid, and has a cast set correctly in its model, it fails like this:
SQLSTATE[22003]: Numeric value out of range: 1416 Cannot get geometry object from data you send to the GEOMETRY
field (SQL: update `checkouts` set `return_location` = POINT(-0.118092 51.509865), `checkouts`.`updated_at` =
2022-12-06 11:03:38 where `user_id` = 4 limit 1)
In other contexts this field works fine.
Is there some limitation I'm running into here, or a bug?
I have a table called locations
containing a Point
column called location
, and if I query it like this:
$point = new Point($lat, $long);
$within = 500;
$locations
->whereDistance('locations.location', $point, '<=', $within)
->orderByDistance('locations.location', $point);
It fails with this error:
Column not found: 1054 Unknown column 'locations.location' in 'where clause' (SQL: select `locations`.* from `locations` where ST_DISTANCE(`locations.location`...
If I change it to ->whereDistance('location', $point, '<=', $within)
(and similarly for the same parameter in the orderByDistance
call), dropping the table name, the query works. If I dump it, I can see that it renders to this SQL:
...where ST_DISTANCE(`location`, ST_GeomFromText(...
However, this would cause ambiguity problems if I had a column with the same name in a different table in the same query.
Is this a bug/limitation in MySQL or in this package?
So we seem to have suddenly developed a problem where converting a polygon to WKT gives not valid WKT and it's only recently started happening.
$polygon = new Polygon(
[
new LineString([
new Point(12.455363273620605, 41.90746728266806),
new Point(12.450309991836548, 41.906636872349075),
new Point(12.445632219314575, 41.90197359839437),
new Point(12.447413206100464, 41.90027269624499),
new Point(12.457906007766724, 41.90000118654431),
new Point(12.458517551422117, 41.90281205461268),
new Point(12.457584142684937, 41.903107507989986),
new Point(12.457734346389769, 41.905918239316286),
new Point(12.45572805404663, 41.90637337450963),
new Point(12.455363273620605, 41.90746728266806),
])
]
);
dd($polygon->toWkt());
This returns:
POLYGON(LINESTRING(POINT(41.907467282668, 12.455363273621),POINT(41.906636872349, 12.450309991837),POINT(41.901973598394, 12.445632219315),POINT(41.900272696245, 12.4474132061),POINT(41.900001186544, 12.457906007767),POINT(41.902812054613, 12.458517551422),POINT(41.90310750799, 12.457584142685),POINT(41.905918239316, 12.45773434639),POINT(41.90637337
451, 12.455728054047),POINT(41.907467282668, 12.455363273621)))
Which is not valid, it should return POLYGON() which this package has been doing previously.
Any ideas on how to resolve would be great!
Hi,
Apologies if this doesn't belong in issues. I am trying to move to this library with this composer command:
composer require matanyadaev/laravel-eloquent-spatial "^2.0"
But I get the following error:
composer/package-versions-deprecated: Generating version class...
composer/package-versions-deprecated: ...done generating version class
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi
PHP Fatal error: Declaration of MatanYadaev\EloquentSpatial\EloquentSpatialServiceProvider::registerDoctrineTypes(Illuminate\Database\Connection $connection): void must be compatible with Illuminate\Database\DatabaseServiceProvider::registerDoctrineTypes() in /Users/kunal/code/opensports/vendor/matanyadaev/laravel-eloquent-spatial/src/EloquentSpatialServiceProvider.php on line 30
In EloquentSpatialServiceProvider.php line 30:
Declaration of MatanYadaev\EloquentSpatial\EloquentSpatialServiceProvider::registerDoctrineTypes(Illuminate\Database\Connection $connection): void must be compatible
with Illuminate\Database\DatabaseServiceProvider::registerDoctrineTypes()
Script @php artisan package:discover --ansi handling the post-autoload-dump event returned with error code 255
Installation failed, reverting ./composer.json and ./composer.lock to their original content.
Any ideas on how to resolve this? Do I need to remove the grimzy / laravel-mysql-spatial
library first and what is the best way to do this in composer?
Thanks heaps.
According to the mysql reference, ST_GeomFromText
does not accept a 3rd parameter on v5.7. On version 2.2 of the laravel-eloquent-spatial library, the axis-order
parameter was introduced as a 3rd parameter, breaking code that runs on installations of MySQL 5.7.
Illuminate\Database\QueryException: SQLSTATE[42000]: Syntax error or access violation: 1582 Incorrect parameter count in the call to native function 'ST_GeomFromText' (SQL: insert into
tablename (
geometry) values ( ST_GeomFromText('POLYGON((-122.48961925507 37.768781090011, -122.48773097992 37.768781090011, -122.48773097992 37.769764882401, -122.48961925507 37.769764882401, -122.48961925507 37.768781090011))', 0, 'axis-order=long-lat'))) in file /vendor/laravel/framework/src/Illuminate/Database/Connection.php on line 759
crosses
, disjoint
, equals
, intersects
, overlaps
...
I want to change display results of coordinates, but for me returned by Geometry class array is completely useless.
I want to return:
[
"latitude": 18.612053,
"longitude": 53.010963
]
How to do that?
I've try to extend Geometry class and add to casts, but i doesn't work.
In your code example you use this in the migration:
$table->point('location')->nullable();
However, if you try to do that and want to search on this field (i.e. it has a spatial index), this will cause an error:
All parts of a SPATIAL index must be NOT NULL
So spatial fields cannot be null at all, which means they must also be initialised to non-null values in a constructor, as that can't be done in the attributes
array, and can't handled by a cast.
But then I run into another issue. If my Location
model has:
public function newEloquentBuilder($query): SpatialBuilder
{
return new SpatialBuilder($query);
}
protected $casts = [
'location' => \MatanYadaev\EloquentSpatial\Objects\Point::class,
];
public function __construct()
{
$this->location = new \MatanYadaev\EloquentSpatial\Objects\Point(51.5032973, -0.1195537);
}
and I do this:
$location = new Location();
$location->save();
it fails with:
TypeError: MatanYadaev\EloquentSpatial\Objects\Geometry::fromWkb(): Argument #1 ($wkb) must be of type string, Illuminate\Database\Query\Expression given, called in vendor/matanyadaev/laravel-eloquent-spatial/src/GeometryCast.php on line 39
How should this be done?
When using with PHPUnit and the SQLiteConnection driver, I encountered a compatibility issue with the AxisOrder class. The issue arises due to the differences in SQL syntax between SQLite and other database systems.
I expected the test cases to run successfully and pass, regardless of the database driver used.
When running the test cases with the SQLiteConnection driver, I encountered errors related to the AxisOrder class. It seems that the SQL syntax used by the library is not compatible with SQLite, resulting in failed queries and test failures.
Here is a simplified example of a failing test case:
use PHPUnit\Framework\TestCase;
use MatanYadaev\EloquentSpatial\Types\Point;
use App\Models\Location;
class SpatialTest extends TestCase
{
public function testSpatialQuery()
{
$location = new Location();
$location->point = new Point(1, 2);
$location->save();
// Perform some spatial queries or assertions
// ...
$this->assertTrue(true);
}
}
Laravel version: ^10
Laravel Eloquent Spatial version:^2.10
PHPUnit version: ^10.0
Database driver: SQLite
Possible fix in Axis
class:
To address the compatibility issue between MatanYadaev/laravel-eloquent-spatial
and SQLiteConnection
, you can modify the Axis
class as follows:
public static function fromWKT($wkt)
{
// ...
// Add conditional check for SQLiteConnection
if (app('db')->connection() instanceof \Illuminate\Database\SQLiteConnection) {
// Handle SQLite-specific behavior here
// For example, convert the WKT to a different format or implement a workaround
// based on the limitations of SQLite's spatial support.
// ...
}
// ...
return $axis;
}
Inside the conditional block, you can implement specific logic or workarounds to handle the limitations of spatial support in SQLite. This could involve converting the WKT format or utilizing SQLite-specific functions.
Save the changes to the Axis.php
file.
Test your application to verify that the compatibility issue has been resolved .
I have tested the same code with other database drivers (e.g., MySQL) and did not encounter any issues.
I have checked the documentation and GitHub repository of the MatanYadaev/laravel-eloquent-spatial library but did not find any specific information regarding SQLite compatibility.
Unlike MySQL, the WKT-input spatial analysis functions in MariaDB (like ST_GeomFromText and ST_DISTANCE) do not take an options parameter: https://mariadb.com/kb/en/st_geomfromtext/
For this reason, we should get an SQL error, while saving the model with spatial fields:
SQLSTATE[42000]: Syntax error or access violation: 1582 Incorrect parameter count in the call to native function 'ST_GeomFromText'
A similar issue was in grimzy/laravel-mysql-spatial and it was fixed by pull request grimzy/laravel-mysql-spatial#152
The AAA (Arrange, Act Assert) pattern's purpose is to organize your test in a way that is easier to read and understand. You can read about it here: https://github.com/goldbergyoni/javascript-testing-best-practices#-%EF%B8%8F-12-structure-tests-by-the-aaa-pattern
In this repo, all of the tests are following this pattern. But it's not perfect, because no comments are separating the test into these 3 sections.
This task is about adding these comments.
Example:
// โ Before
it('calculates sum', function (): void {
$firstNumber = 1;
$secondNumber = 2;
$result = sum($firstNumber, $secondNumber);
expect($result)->toBe(3);
});
// โ
After
it('calculates sum', function (): void {
// Arrange
$firstNumber = 1;
$secondNumber = 2;
// Act
$result = sum($firstNumber, $secondNumber);
// Assert
expect($result)->toBe(3);
});
Real example:
laravel-eloquent-spatial/tests/SpatialBuilderTest.php
Lines 375 to 390 in ce02266
php-cs-fixer
should lint - not fixI have been using https://github.com/grimzy/laravel-mysql-spatial/ which has support for SRIDs. I am planning to migrate to this package as it has greater potential with Laravel's current ecosystem.
But looking at the source code, I don't see any support for SRID which will conflict with my current database schema. Is there any plan or are you interested in a PR?
I have my database.php file looks like this and there is no default connection defined. Its giving me error on composer install.
@MatanYadaev Can you please resolve this?
Thank you for your work on this package! I've been fighting an issue for the past week that I can't find a resolution to. I don't know if this is an issue with this package or Laravel but I thought that I would start here.
I have a queued job that has an object (not a model) as constructor argument. The object has property that is a model with a coordinates (Point) attribute.
something like:
class Report
{
$account = null;
public function __construct(Model $account) {
$this->account = $account
}
}
$account = Account::first();
MakeReport::dispatch(new Report($account));
The coordinates attribute is properly casted on the Account model
protected $casts = [
'coordinates' => Point::class
];
The problem is that the coordinates are not being serialized by laravel and I get the error:
Illuminate\โQueue\โInvalidPayloadException Unable to JSON encode payload. Error code: 5
Any ideas? I'm starting to lose my mind on this.
PHP 8.1.10
Laravel 9.28.0
Laravel 10 was just released. The package apparently supports it without major issues, but the composer.json needs to be updated.
The test coverage today is 100% - in order to maintain it, we'll need to verify it as part of the CI pipeline.
Hi , while inserting data to point i noticed my polygons gets rendered in wrong part of map ,
then i found this
' new LineString([
new Point(23.455363273620605, 45.82746723286806),
new Point(23.450309991836548, 45.826636872349075),
new Point(23.445632219314575, 45.82197359839437),
new Point(23.455363273620605, 45.82746723286806),
]); '
the above code is actually returning the next
{"type":"LineString",
"coordinates":[
[45.82746723286806,23.455363273620605],[45.82663687234908,23.450309991836548],[45.82197359839437,23.445632219314575],[45.82746723286806,23.455363273620605]]}
which is totally wrong,
i temporally fixed it by swapping lats and lngs locations , but it needs to be fixed ,
thank you for your work;;; ๐ฅณ
I want to use "geometry" type like $table->geometry('location')
, but this is not supported because Geometry type declaration for doctrine/dbal is not in /src/Doctrine
. How can I use "geometry" type?
Hi, thank you for your work on this package.
I've tested it with Laravel 10.39.0 and 10.46.0 with your package version 3.2.2 and 4.1.0.
If you are creating a new record or a factory record the column, which includes the point, is always dirty.
Here is an example:
<?php
// Model
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use MatanYadaev\EloquentSpatial\Objects\Point;
use MatanYadaev\EloquentSpatial\Traits\HasSpatial;
class Estate extends Model
{
use HasFactory;
use HasSpatial;
protected $fillable = [
'name',
'coordinates',
];
protected $casts = [
'coordinates' => Point::class,
];
}
<?php
// Factory
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
use MatanYadaev\EloquentSpatial\Objects\Point;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Estate>
*/
class EstateFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'name' => fake()->word(),
'coordinates' => new Point(51.5032973, -0.1217424),
];
}
}
<?php
// Test
use App\Models\Estate;
use MatanYadaev\EloquentSpatial\Objects\Point;
test('coordinates have to be not dirty on factory create', function () {
$estate = Estate::factory()
->create();
expect($estate->isDirty('name'))->toBeFalse();
expect($estate->isDirty('coordinates'))->toBeFalse(); // Failed
});
test('coordinates have to be not dirty on create', function () {
$estate = Estate::create([
'name' => 'Foo',
'coordinates' => new Point(51.5032973, -0.1217424),
]);
expect($estate->isDirty('name'))->toBeFalse();
expect($estate->isDirty('coordinates'))->toBeFalse(); // Failed
});
I've created a demo repository: https://github.com/poldixd/laravel-eloquent-spatial-issue
You can run the test with ./vendor/bin/pest tests/Feature/LaravelEloquentSpatialTest.php
Hello,
At first I would like to thank you for this package. โค๏ธโค๏ธ You are a life saver.
My first impression about this package is awesome, and it satisfies all conditions (at least for me) ๐
But I would like to know how to use Spatial functions ST_Distance_Sphere
By chance, I found the API.md
file and it has a pretty well description however it does not contain more examples.
What I want to do is, instead of creating Database procedures, I want to use ST_Distance_Sphere
Here is a code sample of my project:
// ! show providers listed with in particular distance
$subqueryDistanceFrom = "ST_Distance_Sphere(Point(trips.longitude_from,"
. " trips.latitude_from),"
. " Point($request->long_from, $request->lat_from ))"
. " as distance_from";
$subqueryDistanceTo = "ST_Distance_Sphere(Point(trips.longitude_to,"
. " trips.latitude_to),"
. " Point($request->long_to, $request->lat_to))"
. " as distance_to";
$subqueryDistanceReturnFrom = "ST_Distance_Sphere(Point(trips.longitude_to,"
. " trips.latitude_to),"
. " Point($request->long_from, $request->lat_from ))"
. " as distance_return_from";
$subqueryDistanceReturnTo = "ST_Distance_Sphere(Point(trips.longitude_from,"
. " trips.latitude_from),"
. " Point($request->long_to, $request->lat_to))"
. " as distance_return_to";
$subqueryDistanceWhereFrom = "ST_Distance_Sphere(Point(trips.longitude_from,"
. " trips.latitude_from),"
. " Point($request->long_from, $request->lat_from ))"
. " < " . $distanceDelta;
$subqueryDistanceWhereTo = "ST_Distance_Sphere(Point(trips.longitude_to,"
. " trips.latitude_to),"
. " Point($request->long_to, $request->lat_to ))"
. " < " . $distanceDelta;
$subqueryDistanceWhereReturnFrom = "ST_Distance_Sphere(Point(trips.longitude_to,"
. " trips.latitude_to),"
. " Point($request->long_from, $request->lat_from ))"
. " < " . $distanceDelta;
$subqueryDistanceWhereReturnTo = "ST_Distance_Sphere(Point(trips.longitude_from," . " trips.latitude_from),"
. " Point($request->long_to, $request->lat_to ))" . " < " . $distanceDelta;
I appreciate your help ๐
Hi everyone!
We're facing some problems when storing a polygon with a srid. The problem is that is saving without the srid, so is failing when comparing with other models with srid working.
Example:
$data = "POLYGON((17.03558877746583 -22.543548588275577,17.046918428344735 -22.5888848509733,17.08279565612794 -22.577235171974756,17.122792756958017 -22.572559173452948,17.09824518005372 -22.5226191338314,17.06502870361329 -22.528803166402827,17.03558877746583 -22.543548588275577))";
$polygon = Polygon::fromWkt($data, 4326);
When polygon is stored on DB, srid is not saving.
Can you check it please?
public function setLocationAttribute($value) {
$this->attributes['location'] = new Point($value['lng'], $value['lat']);
}
When I try to update my location column trough setAttribute method I get the following error:
Numeric value out of range: 1416 Cannot get geometry object from data you send to the GEOMETRY field
If I update the column with raw sql query everything works fine.
Using Laravel 10.10 & mysql 8.0
Getting the below error, when querying the table details from the Doctrine Schema Manager, can you assist?
public static function getTable($tableName)
{
$sm = Schema::getConnection()->getDoctrineSchemaManager();
$doctrineTable = $sm->listTableDetails($tableName);
return $doctrineTable;
}
for the following table:
CREATE TABLE 'geo_areas' (
'id' int unsigned NOT NULL AUTO_INCREMENT,
'account_id' int unsigned NOT NULL,
'geo_area_name' varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
'geo_area_region' varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
'geo_area_location' point DEFAULT NULL,
'geo_area_area' polygon DEFAULT NULL,
'created_at' timestamp NULL DEFAULT NULL,
'updated_at' timestamp NULL DEFAULT NULL,
PRIMARY KEY ('id'),
UNIQUE KEY 'geo_areas_geo_area_name_unique' ('geo_area_name'),
KEY 'geo_areas_account_id_foreign' ('account_id'),
CONSTRAINT 'geo_areas_account_id_foreign' FOREIGN KEY ('account_id') REFERENCES 'accounts' ('id') ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Error below:
{
"message": "Unknown database type point requested, Doctrine\\DBAL\\Platforms\\MySQL80Platform may not support it.",
"exception": "Doctrine\\DBAL\\Exception",
"file": "/MySite/vendor/doctrine/dbal/src/Platforms/AbstractPlatform.php",
"line": 418,
"trace": [
{
"file": "/MySite/vendor/doctrine/dbal/src/Schema/MySQLSchemaManager.php",
"line": 176,
"function": "getDoctrineTypeMapping",
"class": "Doctrine\\DBAL\\Platforms\\AbstractPlatform",
"type": "->"
},
{
"file": "/MySite/vendor/doctrine/dbal/src/Schema/AbstractSchemaManager.php",
"line": 1347,
"function": "_getPortableTableColumnDefinition",
"class": "Doctrine\\DBAL\\Schema\\MySQLSchemaManager",
"type": "->"
},
{
"file": "/MySite/vendor/doctrine/dbal/src/Schema/AbstractSchemaManager.php",
"line": 256,
"function": "_getPortableTableColumnList",
"class": "Doctrine\\DBAL\\Schema\\AbstractSchemaManager",
"type": "->"
},
{
"file": "/MySite/vendor/doctrine/dbal/src/Schema/MySQLSchemaManager.php",
"line": 81,
"function": "doListTableColumns",
"class": "Doctrine\\DBAL\\Schema\\AbstractSchemaManager",
"type": "->"
},
{
"file": "/MySite/vendor/doctrine/dbal/src/Schema/AbstractSchemaManager.php",
"line": 476,
"function": "listTableColumns",
"class": "Doctrine\\DBAL\\Schema\\MySQLSchemaManager",
"type": "->"
},
{
"file": "/MySite/vendor/doctrine/dbal/src/Schema/MySQLSchemaManager.php",
"line": 73,
"function": "doListTableDetails",
"class": "Doctrine\\DBAL\\Schema\\AbstractSchemaManager",
"type": "->"
},
{
"file": "/MySite/app/Common/Helpers.php",
"line": 74,
"function": "listTableDetails",
"class": "Doctrine\\DBAL\\Schema\\MySQLSchemaManager",
"type": "->"
},
{
"file": "/MySite/app/Http/Controllers/Controller.php",
"line": 82,
"function": "createIndex",
"class": "App\\Common\\Helpers",
"type": "::"
},
{
"file": "/MySite/app/Http/Controllers/Admin/JobController.php",
"line": 1023,
"function": "MakePaginatedResult",
"class": "App\\Http\\Controllers\\Controller",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Routing/Controller.php",
"line": 54,
"function": "showAllJobsBetweenDatesForAccount",
"class": "App\\Http\\Controllers\\Admin\\JobController",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php",
"line": 43,
"function": "callAction",
"class": "Illuminate\\Routing\\Controller",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Routing/Route.php",
"line": 259,
"function": "dispatch",
"class": "Illuminate\\Routing\\ControllerDispatcher",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Routing/Route.php",
"line": 204,
"function": "runController",
"class": "Illuminate\\Routing\\Route",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
"line": 725,
"function": "run",
"class": "Illuminate\\Routing\\Route",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 141,
"function": "Illuminate\\Routing\\{closure}",
"class": "Illuminate\\Routing\\Router",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/passport/src/Http/Middleware/CheckForAnyScope.php",
"line": 28,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 180,
"function": "handle",
"class": "Laravel\\Passport\\Http\\Middleware\\CheckForAnyScope",
"type": "->"
},
{
"file": "/MySite/app/Http/Middleware/IsClientCredential.php",
"line": 40,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 180,
"function": "handle",
"class": "App\\Http\\Middleware\\IsClientCredential",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php",
"line": 50,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 180,
"function": "handle",
"class": "Illuminate\\Routing\\Middleware\\SubstituteBindings",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php",
"line": 126,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php",
"line": 62,
"function": "handleRequest",
"class": "Illuminate\\Routing\\Middleware\\ThrottleRequests",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 180,
"function": "handle",
"class": "Illuminate\\Routing\\Middleware\\ThrottleRequests",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php",
"line": 44,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 180,
"function": "handle",
"class": "Illuminate\\Auth\\Middleware\\Authenticate",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 116,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
"line": 726,
"function": "then",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
"line": 703,
"function": "runRouteWithinStack",
"class": "Illuminate\\Routing\\Router",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
"line": 667,
"function": "runRoute",
"class": "Illuminate\\Routing\\Router",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
"line": 656,
"function": "dispatchToRoute",
"class": "Illuminate\\Routing\\Router",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
"line": 190,
"function": "dispatch",
"class": "Illuminate\\Routing\\Router",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 141,
"function": "Illuminate\\Foundation\\Http\\{closure}",
"class": "Illuminate\\Foundation\\Http\\Kernel",
"type": "->"
},
{
"file": "/MySite/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Http/SetRequestIpMiddleware.php",
"line": 45,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 180,
"function": "handle",
"class": "Sentry\\Laravel\\Http\\SetRequestIpMiddleware",
"type": "->"
},
{
"file": "/MySite/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Http/SetRequestMiddleware.php",
"line": 31,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 180,
"function": "handle",
"class": "Sentry\\Laravel\\Http\\SetRequestMiddleware",
"type": "->"
},
{
"file": "/MySite/app/Http/Middleware/DbSelector.php",
"line": 37,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 180,
"function": "handle",
"class": "App\\Http\\Middleware\\DbSelector",
"type": "->"
},
{
"file": "/MySite/app/Http/Middleware/Cors.php",
"line": 32,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 180,
"function": "handle",
"class": "App\\Http\\Middleware\\Cors",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php",
"line": 21,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php",
"line": 31,
"function": "handle",
"class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 180,
"function": "handle",
"class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php",
"line": 21,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php",
"line": 40,
"function": "handle",
"class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 180,
"function": "handle",
"class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php",
"line": 27,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 180,
"function": "handle",
"class": "Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php",
"line": 86,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 180,
"function": "handle",
"class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php",
"line": 39,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 180,
"function": "handle",
"class": "Illuminate\\Http\\Middleware\\TrustProxies",
"type": "->"
},
{
"file": "/MySite/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Tracing/Middleware.php",
"line": 53,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 180,
"function": "handle",
"class": "Sentry\\Laravel\\Tracing\\Middleware",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
"line": 116,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
"line": 165,
"function": "then",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "/MySite/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
"line": 134,
"function": "sendRequestThroughRouter",
"class": "Illuminate\\Foundation\\Http\\Kernel",
"type": "->"
},
{
"file": "/MySite/public/index.php",
"line": 53,
"function": "handle",
"class": "Illuminate\\Foundation\\Http\\Kernel",
"type": "->"
},
{
"file": "/Users/ricardonolan/.composer/vendor/laravel/valet/server.php",
"line": 234,
"function": "require"
}
]
}
Hi, this is not an issue, I just need help with something, if that's alright.
I pull google map bounds, and the result I get is this:
{ south: 44.85856815478515, west: 12.956013352988899, north: 46.61810356385327, east: 18.40797868502015 }
or this:
North-east:
{ lat: 46.61810356385327, lng: 18.40797868502015}
South-west:
{ lat: 44.85856815478515, lng: 12.956013352988899 }
What I'm trying to do is fetch Locations form my MySQL database within those bounds. I've figured I probably need to use whereWithin()
method, which accepts Geometry
as the second argument. How do I make an instance of Geometry
with the data that I have?
Is it as simple as just translating those point to south-east and north-west, and then creating a Polygon
using fromJson
, or is there more to it?
Thanks!
When returning a collection with some spatial fields in it (in our case, all Point's) like this:
return response()->json($res);
We get a 500 error on the server with "Malformed UTF-8 characters, possibly incorrectly encoded".
As soon as I null the spatial field in the DB, the error dissolves. It seemingly is unable to correctly create a json out of the field.
Using latest Laravel 9 and current master.
The bug appears after approximately 40 - 60 secs of instance lifetime, probably due connection outdating.... In regular FPM mode it is working as expected.
{
"class": "Error",
"message": "Call to a member function getAttribute() on null",
"code": 0,
"file": "/var/task/vendor/laravel/framework/src/Illuminate/Database/MySqlConnection.php:23",
"trace": [
"/var/task/vendor/matanyadaev/laravel-eloquent-spatial/src/AxisOrder.php:34",
"/var/task/vendor/matanyadaev/laravel-eloquent-spatial/src/AxisOrder.php:18",
"/var/task/vendor/matanyadaev/laravel-eloquent-spatial/src/Objects/Geometry.php:219",
"/var/task/vendor/matanyadaev/laravel-eloquent-spatial/src/SpatialBuilder.php:326",
"/var/task/vendor/matanyadaev/laravel-eloquent-spatial/src/SpatialBuilder.php:95",
"/var/task/app/Domain/Car/Actions/GetChargingStations.php:111",
"/var/task/vendor/laravel/framework/src/Illuminate/Conditionable/Traits/Conditionable.php:34",
"/var/task/app/Domain/Car/Actions/GetChargingStations.php:114",
"/var/task/app/Domain/Car/Actions/GetChargingStations.php:29",
"/var/task/app/Domain/Car/Http/Controllers/Api/ChargingStationController.php:469",
Hi!,
i am trying to implement draft functionality on model. in that while trying to swap two records. i am facing Expected MatanYadaev\EloquentSpatial\GeometryCast, string given
this type of error.
Updating location data doesn't work.
Below is the snapshot of swapping code.
$oldAttributes = $published?->getAttributes() ?? [];
$newAttributes = $this->getAttributes();
Arr::forget($oldAttributes, $this->getKeyName());
Arr::forget($newAttributes, $this->getKeyName());
$published->forceFill($newAttributes);
$this->forceFill($oldAttributes);
The field is casted in model as
location' => Point::class,
in the migration the field is created as
$table->point('location')->nullable();
Using Laravel-Drafts package for implementing draft functionality.
I have a column that can be either a Point
or a Polygon
, so this column has the generic geometry
type. But I'm getting an error when I cast it.
Illuminate\Database\QueryException: SQLSTATE[HY093]: Invalid parameter number (SQL: insert into `areas` (`name`, `type`, `city_id`, `region_id`, `description`, `ai_description`, `country_id`, `geometry`, `centroid`, `updated_at`, `created_at`) values (Priceport, NH, sublocality_level_2, 1697, 3286, Tempore sint molestiae distinctio porro ab vel. Exercitationem quam illum rerum enim nam quidem. Ut soluta dicta quos iste., Et totam velit corrupti voluptatum nobis perferendis magnam. Quia non asperiores quas nihil. Qui sit at voluptate quam dolorem consequatur., 914, ST_GeomFromText('POINT(113.417617 -24.459282)', 4326, 'axis-order=long-lat'), ST_GeomFromText(2024-01-29 06:07:51, 2024-01-29 06:07:51, 'axis-order=long-lat'), ?, ?))
/var/www/datacontent/vendor/laravel/framework/src/Illuminate/Database/Connection.php:760
/var/www/datacontent/vendor/laravel/framework/src/Illuminate/Database/Connection.php:720
/var/www/datacontent/vendor/laravel/framework/src/Illuminate/Database/Connection.php:546
/var/www/datacontent/vendor/laravel/framework/src/Illuminate/Database/Connection.php:498
/var/www/datacontent/vendor/laravel/framework/src/Illuminate/Database/Query/Processors/Processor.php:32
/var/www/datacontent/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:3322
/var/www/datacontent/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:1869
/var/www/datacontent/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:1330
/var/www/datacontent/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:1295
/var/www/datacontent/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:1138
/var/www/datacontent/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Factories/Factory.php:330
/var/www/datacontent/vendor/laravel/framework/src/Illuminate/Collections/Traits/EnumeratesValues.php:235
/var/www/datacontent/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Factories/Factory.php:339
/var/www/datacontent/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Factories/Factory.php:283
/var/www/datacontent/tests/Feature/Controllers/Api/LocationControllerTest.php:54
Caused by
PDOException: SQLSTATE[HY093]: Invalid parameter number
/var/www/datacontent/vendor/laravel/framework/src/Illuminate/Database/Connection.php:545
/var/www/datacontent/vendor/laravel/framework/src/Illuminate/Database/Connection.php:753
/var/www/datacontent/vendor/laravel/framework/src/Illuminate/Database/Connection.php:720
/var/www/datacontent/vendor/laravel/framework/src/Illuminate/Database/Connection.php:546
/var/www/datacontent/vendor/laravel/framework/src/Illuminate/Database/Connection.php:498
/var/www/datacontent/vendor/laravel/framework/src/Illuminate/Database/Query/Processors/Processor.php:32
/var/www/datacontent/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:3322
/var/www/datacontent/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:1869
/var/www/datacontent/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:1330
/var/www/datacontent/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:1295
/var/www/datacontent/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:1138
/var/www/datacontent/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Factories/Factory.php:330
/var/www/datacontent/vendor/laravel/framework/src/Illuminate/Collections/Traits/EnumeratesValues.php:235
/var/www/datacontent/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Factories/Factory.php:339
/var/www/datacontent/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Factories/Factory.php:283
/var/www/datacontent/tests/Feature/Controllers/Api/LocationControllerTest.php:54
phpunit.xml
<server name="DB_CONNECTION" value="sqlite"/>
<server name="DB_DATABASE" value=":memory:"/>
I write a FeatureTest which creates a model through a factory, and the factory looks like this:
public function definition(): array
{
return [
...
'address' => $this->faker->address(),
'point' => new Point($this->faker->latitude, $this->faker->longitude),
...
];
}
Inside my test, I execute the following code: MyModel::factory()->create()
and I get the following error
Error:
MatanYadaev\EloquentSpatial\AxisOrder::isMariaDb(): Argument #1 ($connection) must be of type Illuminate\Database\MySqlConnection, Illuminate\Database\SQLiteConnection given, called in /app/vendor/matanyadaev/laravel-eloquent-spatial/src/AxisOrder.php on line 18
I can somehow make it work with sql-lite?
After the recent change that removes SpatialBuilder (#102), I am trying to use Spatie QueryBuilder to sort by distance.
$businesses = QueryBuilder::for(Business::class)
->allowedSorts([
AllowedSort::custom('distance', new AddressDistanceSort()),
])
->paginate()
->withQueryString();
class AddressDistanceSort implements Sort
{
public function __invoke(Builder $query, bool $descending, string $property)
{
$point = new Point(request()->latitude, request()->longitude, Srid::WGS84->value);
$query->with(['address' => function ($query) use ($point, $descending) {
$query->withDistance('location', $point);
}]);
// How to apply orderByDistance here???
}
}
Obviously I'm not saying it's a bug in the Spatial package, but I think a lot of Laravel developers use Spatie QueryBuilder and I was wondering if anyone has managed to get this to work.
Could this package work together with Spatie QueryBuilder?
Thank you very much for your help and for this great package.
Laravel: 10.1.5
matanyadaev/laravel-eloquent-spatial: 3.1.2
Query example:
Users::whereDistanceSphere('location', $user->location, '<', 20)->get()
Error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'distance_sphere' in 'where clause' (Connection: mysql, SQL: select * from `users` where `distance_sphere` = location)
What do I do wrong?
It would be brilliant if the API spatial scopes could be expanded to support ST_Buffer
, e.g.
Filters records within a buffer. Uses ST_Buffer.
parameter name | type |
---|---|
$column |
Geometry \ string |
$geometryOrColumn |
Geometry \ string |
$value |
int \ float |
Place::create(['location' => new Point(1, 1.5)]);
$placesCountWithinBuffer = Place::query()
->whereBuffer('location', Polygon::fromJson('{"type":"Polygon","coordinates":[[[-1,-1],[1,-1],[1,1],[-1,1],[-1,-1]]]}'), 3)
->count();
echo $placesCountWithinBuffer; // 1
I will see if I can submit a PR, but with Christmas coming up it won't be for a little while!
I'm using Laravel Eloquent Spatial in my project.
Despite I've could used it pretty well when selecting Point objects within a Polygon geometry, I had to create a raw SQL request to use those MySQL Spatial methods.
Here's my code of a method in my app, used to return a Point geometry with the centroid of a polygon:
public function centroide(array $featurePoligono){
error_log(json_encode($featurePoligono)); //{"type":"Feature" ...}
error_log(json_encode($featurePoligono['geometry'])); //{"type":"Polygon" ...}
$dbQuery=DB::select('SELECT ST_AsGeoJSON(ST_Centroid(ST_GeomFromGeoJSON(\''. json_encode($featurePoligono) .'\')))');
$centroide=array_values((array)$dbQuery[0])[0];
error_log($centroide); //{"type": "Point", "coordinates": [-58.424712150445174, -34.605689506111084]}
error_log(gettype($centroide)); //string
error_log(get_class(json_decode($centroide))); //stdClass
return (array)json_decode($centroide);
}
Is there any way to achieve this using Laravel Eloquent Spatial?
Hi,
The factory class seems to be swapping the values of latitude and longitude. See the code below. Why is that? I'm using MariaDB v. 10.5. with Laravel 9.
protected static function createFromGeometry(geoPHPGeometry $geometry): Geometry
{
if ($geometry instanceof geoPHPPoint) {
return new Point($geometry->coords[1], $geometry->coords[0]);
}
}
error:
Unable to encode attribute [original] for model [Laravel\Nova\Actions\ActionEvent] to JSON: Malformed UTF-8 characters, possibly incorrectly encoded.
It would be quite nice to include validation rules that could be used in form validations to validate appropriate JSON representations of each class.
For example, we could then validate requests using:
use MatanYadaev\EloquentSpatial\Rules\Point;
$request->validate([
'location' => ['required', new Point],
]);
rather than having to do it manually, such as:
$request->validate([
'location' => ['required', 'array:type,coordinates'],
'location.type' => ['required', 'in:Point'],
'location.coordinates' => ['required', 'array:0,1'],
'location.coordinates.0' => ['required', 'numeric', 'min:-90', 'max:90'],
'location.coordinates.1' => ['required', 'numeric', 'min:-180', 'max:180'],
]);
Unless I'm being a bit thick and can do it more easily than this?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.