How convert LONGBLOB to GEOMETRY data in mySQL? - mysql

I have tables with geodata on corporate mySQL server.
MINX:int(10),MAXX:int(10),MINY:int(10),MAXY:int(10),ObjectStyle:bigint(20),LINE:longblob
Example:
2192984,2192984,8189022,8189022,294775458895766961,2,0x02000000010001000000010001000000587621005EF47C00000000000000803F0000803F00000000010000005B17ADC8091B7747000000000000803F00000000000000000000000000
or:
create table stations
(
MINX int(10) null comment 'Left object boundary on Ox',
MAXX int(10) null comment 'Right boundary of the object on Ox',
MINY int(10) null comment 'Lower boundary of the object along the Oy axis',
MAXY int(10) null comment 'Upper boundary of the object along the Oy axis',
ObjectStyle bigint null comment 'Object style identifier',
LINE longblob null comment 'Object coordinates
);
INSERT INTO stations ( MINX, MAXX, MINY, MAXY, ObjectStyle, LINE) VALUES (2192984, 2192984, 8189022, 8189022, 294775458895766961, 0x02000000010001000000010001000000587621005EF47C00000000000000803F0000803F00000000010000005B17ADC8091B7747000000000000803F00000000000000000000000000);
May be wrong srid? I tried use 4326
I tried to convert longblob to varchar.
I tried
select linefromwkb(LINE) from stations
I tried select GEOMETRYFROMWKB(LINE, 4326) from stations <- i get [22001][3037] Data truncation: Invalid GIS data provided to function st_geometryfromwkb.

Related

MSQL Maria DB what type field for polygon coordinates and how to save the polygon coordinates

I am trying to save polygon coordinates into MYSQL database. Later On I will have to search this table if a given LAT&LNG is within any saved coordinates.
So far I have created table :
DROP TABLE IF EXISTS `zoni`;
CREATE TABLE `zoni` (
`id` int(11) NOT NULL,
`zone_name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`coordinates` multipolygon NOT NULL,
`prioritet` int(1) NOT NULL DEFAULT 1,
`added_date` datetime NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=utf8_general_ci;
From JS code thanks to [this post][1]
I am getting coordinates and save them in
<input type="hidden" name="coordinates" id="coordinates" value="(42.50665658278373, 27.463869916146855),(42.50646675964302, 27.464545832818608),(42.5061741145051, 27.463827000802617),(42.50640348513469, 27.463548051065068)"/>
and when execute this query:
insert into zoni set zone_name="Zone 1", prioritet="1",
coordinates="42.50665658278373, 27.463869916146855,42.50646675964302, 27.464545832818608,42.5061741145051, 27.463827000802617,42.50640348513469, 27.463548051065068", added_date= now()
I am getting this ERROR:
Cannot get geometry object from data you send to the GEOMETRY field
What is the correct field type I should change and how the query should looks like?
I apreciate your time and help !
[1]: Google Maps Draw Tool outputting polygon coordinates

How to look up multipolygon data in mysql by coordinates

// 맵 데이터
db.Exec(`CREATE TABLE IF NOT EXISTS
geo_datas(
id bigint unsigned primary key auto_increment,
level tinyint unsigned NOT NULL,
geom multipolygon NOT NULL,
country_name varchar(30) NOT NULL,
country_code varchar(10) NOT NULL,
name varchar(50),
minx REAL NOT NULL,
miny REAL NOT NULL,
maxx REAL NOT NULL,
maxy REAL NOT NULL
)
`)
Data is created in the table created with the code above. The geom column is a multipolygon type, and the following data is inserted.
MULTIPOLYGON (((5.347486495971623 45.98247528076172, 5.3532729148865315 45.991767883300895, 5.3617901802064125 45.99477386474615, 5.37621974945074 45.99368667602545, 5.380286693572998 45.98820495605469, 5.3969597816467285 45.981689453125, 5.396285533905029 45.97837066650396, 5.378274440765438 45.97423934936529, 5.347486495971623 45.98247528076172)))
After that, I wanted to get the multipolygon data to which the coordinates belong as a map coordinate point type, and I tried the following.
SELECT id
FROM geo_datas
WHERE MBRContains(geom , ST_GeomFromText('Point(37.543238571036824 126.9867128133774)'));
When I executed the above sql, it ran for 201 seconds.
And it returned 0 results.
The data I have is world data, a result of 0 is impossible, I don't know why it returns 0.
The query is also very slow, I don't know how to solve it, please give me some advice, can I have a simple example?
ALTER TABLE geo_datas
ADD SPATIAL(multipolygon);
_, err = db.Exec(`CREATE TABLE IF NOT EXISTS
geo_datas(
id bigint unsigned primary key auto_increment,
level tinyint unsigned NOT NULL,
geom multipolygon NOT NULL SRID 0,
country_name varchar(30) NOT NULL,
country_code varchar(10) NOT NULL,
name varchar(50),
minx REAL NOT NULL,
miny REAL NOT NULL,
maxx REAL NOT NULL,
maxy REAL NOT NULL,
index idx_level (level),
index idx_country_code (country_code),
index idx_country_name (country_name),
index idx_name (name),
spatial index (geom)
)
`)
i changed the table as above code
query := "SELECT level, name, country_name, country_code, ST_AsGeoJSON(geom, 20) geom " +
"FROM geo_datas " +
"WHERE ST_Contains(geom, ST_GeomFromText('Point(%v %v)')) " +
"ORDER BY level asc "
After changing the code as above, everyting working fine.

mysql8 nearest place using radius filter

First of all, I am using mysql8.
I have a table that store states of my country.
My table ddl is:
CREATE TABLE state_v2(
`id` int(11) NOT NULL,
uf_code INT NULL,
uf VARCHAR(2) NOT NULL,
`name` VARCHAR(100) NOT NULL,
latitude FLOAT(8) NOT NULL,
longitude FLOAT(8) NOT NULL,
`country` varchar(75) NOT NULL,
coord POINT SRID 4326 NOT NULL,
PRIMARY KEY (id),
unique (country, uf_code),
unique (latitude, longitude),
index (uf_code)
);
ALTER TABLE state_v2 ADD SPATIAL INDEX(coord);
The user choose a place and I use this place as reference to find the nearest state less then 100km. (the parameter is a correct point).
I am using this query:
SELECT * FROM (
SELECT
sv.*,
ST_distance_sphere(
$param,
sv.coord) as distance
FROM state_v2 sv
WHERE ST_distance_sphere(
$param,
sv.coord) < 100000
) as temp
order by temp.distance;
1 - Is it correct this query? I am worried about the performance of using like that, it is using full table scan.
2 - Is it correct the created indexes?

mySQL import failing on DECIMAL

I am trying to import some fields into a MySQL database, here is my import file...
CREATE TABLE mytable(
zip VARCHAR(7) NOT NULL PRIMARY KEY
,lat DECIMAL(10,8) NOT NULL
,long DECIMAL(11,8) NOT NULL
,data VARCHAR(3) NOT NULL
);
It is giving me the following error...
check the manual that corresponds to your MySQL server version for the right syntax to use near 'long DECIMAL(11,8) NOT NULL ,data VARCHAR(3) NOT NULL )' at line 4
It is not liking the long field that I am trying to set as DECIMAL type
Where am I going wrong?
The long is the reserved keyword in MySQL. Try using escaping like this:
CREATE TABLE mytable
(zip VARCHAR(7) NOT NULL PRIMARY KEY
,lat DECIMAL(10,8) NOT NULL
,`long` DECIMAL(11,8) NOT NULL
,data VARCHAR(3) NOT NULL
);
Or, what is better, try using another name. For latitude and longitude this might be lat and lng or lat and lon.

MySql How to convert varchar (latitude, longitude) to Decimal fields?

In mysql I have a varchar containing latitude and longitude provided by Google maps.
I need to be able to query based on a bounding box value, but have no need for the geo features now available. I'm trying to populate 2 new Decimal fields with the Decimal values found in the varchar. Here is the query that I'm trying to use, but the result are all rounded values in the new fields.
Sample data:
'45.390746926938185, -122.75535710155964',
'45.416444621636415, -122.63058006763458'
Create Table:
CREATE TABLE IF NOT EXISTS `cameras` (
`id` int(11) NOT NULL auto_increment,
`user_id` int(75) NOT NULL,
`position` varchar(75) NOT NULL,
`latitude` decimal(17,15) default NULL,
`longitude` decimal(18,15) default NULL,
`address` varchar(75) NOT NULL,<br />
`date` varchar(11) NOT NULL,<br />
`status` int(1) NOT NULL default '1',
`duplicate_report` int(11) NOT NULL default '0',
`missing_report` int(11) NOT NULL default '0',
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
KEY `status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1050 ;
SQL:
UPDATE cameras
SET latitude = CAST( (substring(position,1,locate(',',position))) AS DECIMAL(17,15) ),
longitude = CAST( (substring(position,locate(',',position)+1)) AS DECIMAL(18,15) )
SQL Alternate attempt:
UPDATE cameras
SET latitude = CONVERT( (substring(position,1,locate(',',position))), DECIMAL(17,15) ),
longitude = CONVERT( (substring(position,locate(', ',position)+1)), DECIMAL(18,15) )
The resulting field values are for both scenarios:
45.000000000000000 and -122.000000000000000
AND
45.000000000000000 and -122.000000000000000
Can anyone see what I'm doing wrong?
Thanks.
Both the CAST and CONVERT forms seem to be correct.
SELECT CAST((SUBSTRING(t.position,1,LOCATE(',',t.position))) AS DECIMAL(17,15)) AS lat_
, CONVERT(SUBSTRING(t.position,LOCATE(', ',t.position)+1),DECIMAL(18,15)) AS long_
FROM (SELECT '45.390746926938185, -122.75535710155964' AS `position`) t
lat_ long_
------------------ ----------------------
45.390746926938185 -122.755357101559640
I think position is a reserved word, but I don't think that matters in this case. But it wouldn't hurt to assign a table alias and qualify all column references
UPDATE cameras c
SET c.latitude = CAST((SUBSTRING(c.position,1,LOCATE(',',c.position))) AS DECIMAL(17,15))
, c.longitude = CAST((SUBSTRING(c.position,LOCATE(',',c.position)+1)) AS DECIMAL(18,15))
But I suspect that won't resolve the problem.
One thing to check is for a before or after update trigger defined on the table, which is rounding/modifying the values assigned to the latitude and longitude columns?
I suggest you try running just a query.
SELECT CAST((SUBSTRING(c.position,1,LOCATE(',',c.position))) AS DECIMAL(17,15)) AS lat_
, CAST((SUBSTRING(c.position,LOCATE(',',c.position)+1)) AS DECIMAL(18,15)) AS lon_
FROM cameras c
and verify that produces the decimal values you expect.
A dot character should be recognized as a decimal point. Does the position column contain some other special characters, like a space or something?
From what you posted, it looks like the CAST and CONVERT working on the integer portion up to the decimal point. (There shouldn't be an implicit convert to signed integer in there, so it's not clear why the characters following the decimal point aren't being included.)
If you can figure out what character(s) are being used to represent the decimal point, then you could use a MySQL REPLACE() function to replace those with a simple dot character.