-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[GRASS][FEATURE] vector import via browser drag and drop
- ltr-3_40
- ltr-3_34
- ltr-3_28
- ltr-3_22
- ltr-3_16
- ltr-3_10
- ltr-3_4
- ltr-2_18
- ltr-2_14
- final-3_40_2
- final-3_40_1
- final-3_40_0
- final-3_38_3
- final-3_38_2
- final-3_38_1
- final-3_38_0
- final-3_36_3
- final-3_36_2
- final-3_36_1
- final-3_36_0
- final-3_34_14
- final-3_34_13
- final-3_34_12
- final-3_34_11
- final-3_34_10
- final-3_34_9
- final-3_34_8
- final-3_34_7
- final-3_34_6
- final-3_34_5
- final-3_34_4
- final-3_34_3
- final-3_34_2
- final-3_34_1
- final-3_34_0
- final-3_32_3
- final-3_32_2
- final-3_32_1
- final-3_32_0
- final-3_30_3
- final-3_30_2
- final-3_30_1
- final-3_30_0
- final-3_28_15
- final-3_28_14
- final-3_28_13
- final-3_28_12
- final-3_28_11
- final-3_28_10
- final-3_28_9
- final-3_28_8
- final-3_28_7
- final-3_28_6
- final-3_28_5
- final-3_28_4
- final-3_28_3
- final-3_28_2
- final-3_28_1
- final-3_28_0
- final-3_26_3
- final-3_26_2
- final-3_26_1
- final-3_26_0
- final-3_24_3
- final-3_24_2
- final-3_24_1
- final-3_24_0
- final-3_22_16
- final-3_22_15
- final-3_22_14
- final-3_22_13
- final-3_22_12
- final-3_22_11
- final-3_22_10
- final-3_22_9
- final-3_22_8
- final-3_22_7
- final-3_22_6
- final-3_22_5
- final-3_22_4
- final-3_22_3
- final-3_22_2
- final-3_22_1
- final-3_22_0
- final-3_20_3
- final-3_20_2
- final-3_20_1
- final-3_20_0
- final-3_18_3
- final-3_18_2
- final-3_18_1
- final-3_18_0
- final-3_16_16
- final-3_16_15
- final-3_16_14
- final-3_16_13
- final-3_16_12
- final-3_16_11
- final-3_16_10
- final-3_16_9
- final-3_16_8
- final-3_16_7
- final-3_16_6
- final-3_16_5
- final-3_16_4
- final-3_16_3
- final-3_16_2
- final-3_16_1
- final-3_16_0
- final-3_14_16
- final-3_14_15
- final-3_14_1
- final-3_14_0
- final-3_12_3
- final-3_12_2
- final-3_12_1
- final-3_12_0
- final-3_10_14
- final-3_10_13
- final-3_10_12
- final-3_10_11
- final-3_10_10
- final-3_10_9
- final-3_10_8
- final-3_10_7
- final-3_10_6
- final-3_10_5
- final-3_10_4
- final-3_10_3
- final-3_10_2
- final-3_10_1
- final-3_10_0
- final-3_8_3
- final-3_8_2
- final-3_8_1
- final-3_8_0
- final-3_6_3
- final-3_6_2
- final-3_6_1
- final-3_6_0
- final-3_4_15
- final-3_4_14
- final-3_4_13
- final-3_4_12
- final-3_4_11
- final-3_4_10
- final-3_4_9
- final-3_4_8
- final-3_4_7
- final-3_4_6
- final-3_4_5
- final-3_4_4
- final-3_4_3
- final-3_4_2
- final-3_4_1
- final-3_4_0
- final-3_2_3
- final-3_2_2
- final-3_2_1
- final-3_2_0
- final-3_0_3
- final-3_0_2
- final-3_0_1
- final-3_0_0
- final-2_18_28
- final-2_18_27
- final-2_18_26
- final-2_18_25
- final-2_18_24
- final-2_18_23
- final-2_18_22
- final-2_18_21
- final-2_18_20
- final-2_18_19
- final-2_18_18
- final-2_18_17
- final-2_18_16
- final-2_18_15
- final-2_18_14
- final-2_18_13
- final-2_18_12
- final-2_18_11
- final-2_18_10
- final-2_18_9
- final-2_18_8
- final-2_18_7
- final-2_18_6
- final-2_18_5
- final-2_18_4
- final-2_18_3
- final-2_18_2
- final-2_18_1
- final-2_18_0
- final-2_16_3
- final-2_16_2
- final-2_16_1
- final-2_16_0
- final-2_14_22
- final-2_14_21
- final-2_14_20
- final-2_14_19
- final-2_14_18
- final-2_14_17
- final-2_14_16
- final-2_14_15
- final-2_14_14
- final-2_14_13
- final-2_14_12
- final-2_14_11
- final-2_14_10
- final-2_14_9
- final-2_14_8
- final-2_14_7
- final-2_14_6
- final-2_14_5
- final-2_14_4
- final-2_14_3
- final-2_14_2
- final-2_14_1
- final-2_14_0
- final-2_12_3
- final-2_12_2
- final-2_12_1
- final-2_12_0
- final-2_10_1
- final-2_10_0
- archive/master_2
Showing
10 changed files
with
881 additions
and
91 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,331 @@ | ||
/*************************************************************************** | ||
qgis.v.in.cpp | ||
--------------------- | ||
begin : May 2015 | ||
copyright : (C) 2015 by Radim Blazek | ||
email : radim dot blazek at gmail dot com | ||
*************************************************************************** | ||
* * | ||
* This program is free software; you can redistribute it and/or modify * | ||
* it under the terms of the GNU General Public License as published by * | ||
* the Free Software Foundation; either version 2 of the License, or * | ||
* (at your option) any later version. * | ||
* * | ||
***************************************************************************/ | ||
|
||
extern "C" | ||
{ | ||
#include <stdlib.h> | ||
#include <stdio.h> | ||
#include <string.h> | ||
#include <math.h> | ||
#include <assert.h> | ||
#ifdef WIN32 | ||
#include <fcntl.h> | ||
#include <io.h> | ||
#endif | ||
#include <grass/version.h> | ||
#include <grass/gis.h> | ||
#include <grass/dbmi.h> | ||
|
||
#if GRASS_VERSION_MAJOR < 7 | ||
#include <grass/Vect.h> | ||
#else | ||
#include <grass/vector.h> | ||
#endif | ||
} | ||
|
||
#include <QByteArray> | ||
#include <QDataStream> | ||
#include <QFile> | ||
#include <QIODevice> | ||
|
||
#include "qgsfeature.h" | ||
#include "qgsgeometry.h" | ||
#include "qgsrectangle.h" | ||
#include "qgsrasterblock.h" | ||
#include "qgsspatialindex.h" | ||
#include "qgsgrass.h" | ||
|
||
static struct line_pnts *line = Vect_new_line_struct(); | ||
|
||
void writePoint( struct Map_info* map, int type, QgsPoint point, struct line_cats *cats ) | ||
{ | ||
Vect_reset_line( line ); | ||
Vect_append_point( line, point.x(), point.y(), 0 ); | ||
Vect_write_line( map, type, line, cats ); | ||
} | ||
|
||
void writePolyline( struct Map_info* map, int type, QgsPolyline polyline, struct line_cats *cats ) | ||
{ | ||
Vect_reset_line( line ); | ||
foreach ( QgsPoint point, polyline ) | ||
{ | ||
Vect_append_point( line, point.x(), point.y(), 0 ); | ||
} | ||
Vect_write_line( map, type, line, cats ); | ||
} | ||
|
||
int main( int argc, char **argv ) | ||
{ | ||
struct Option *mapOption; | ||
|
||
G_gisinit( argv[0] ); | ||
G_define_module(); | ||
mapOption = G_define_standard_option( G_OPT_V_OUTPUT ); | ||
|
||
if ( G_parser( argc, argv ) ) | ||
exit( EXIT_FAILURE ); | ||
|
||
QFile stdinFile; | ||
stdinFile.open( 0, QIODevice::ReadOnly ); | ||
QDataStream stdinStream( &stdinFile ); | ||
|
||
QFile stdoutFile; | ||
stdoutFile.open( 0, QIODevice::ReadOnly ); | ||
QDataStream stdoutStream( &stdoutFile ); | ||
|
||
qint32 typeQint32; | ||
stdinStream >> typeQint32; | ||
QGis::WkbType wkbType = ( QGis::WkbType )typeQint32; | ||
QGis::WkbType wkbFlatType = QGis::flatType( wkbType ); | ||
bool isPolygon = QGis::singleType( wkbFlatType ) == QGis::WKBPolygon; | ||
|
||
struct Map_info finalMap, tmpMap; | ||
Vect_open_new( &finalMap, mapOption->answer, 0 ); | ||
struct Map_info * map = &finalMap; | ||
QDateTime now = QDateTime::currentDateTime(); | ||
QString tmpName = QString( "%1_tmp_%2" ).arg( mapOption->answer ).arg( now.toString( "yyyyMMddhhmmss" ) ); | ||
if ( isPolygon ) | ||
{ | ||
Vect_open_new( &tmpMap, tmpName.toUtf8().data(), 0 ); | ||
map = &tmpMap; | ||
} | ||
|
||
QgsFields srcFields; | ||
stdinStream >> srcFields; | ||
// TODO: find (in QgsGrassVectorImport) if there is unique 'id' or 'cat' field and use it as cat | ||
int keyNum = 1; | ||
QString key; | ||
while ( true ) | ||
{ | ||
key = "cat" + ( keyNum == 1 ? "" : QString::number( keyNum ) ); | ||
if ( srcFields.indexFromName( key ) == -1 ) | ||
{ | ||
break; | ||
} | ||
keyNum++; | ||
} | ||
|
||
QgsFields fields; | ||
fields.append( QgsField( key, QVariant::Int ) ); | ||
fields.extend( srcFields ); | ||
|
||
struct field_info *fieldInfo = Vect_default_field_info( &finalMap, 1, NULL, GV_1TABLE ); | ||
if ( Vect_map_add_dblink( &finalMap, 1, NULL, fieldInfo->table, key.toLatin1().data(), | ||
fieldInfo->database, fieldInfo->driver ) != 0 ) | ||
{ | ||
G_fatal_error( "Cannot add link" ); | ||
} | ||
|
||
dbDriver *driver = db_start_driver_open_database( fieldInfo->driver, fieldInfo->database ); | ||
if ( !driver ) | ||
{ | ||
G_fatal_error( "Cannot open database %s by driver %s", fieldInfo->database, fieldInfo->driver ); | ||
} | ||
try | ||
{ | ||
QgsGrass::createTable( driver, QString( fieldInfo->table ), fields ); | ||
} | ||
catch ( QgsGrass::Exception &e ) | ||
{ | ||
G_fatal_error( "Cannot create table: %s", e.what() ); | ||
} | ||
|
||
QgsFeature feature; | ||
struct line_cats *cats = Vect_new_cats_struct(); | ||
|
||
qint32 featureCount = 0; | ||
while ( true ) | ||
{ | ||
stdinStream >> feature; | ||
if ( !feature.isValid() ) | ||
{ | ||
break; | ||
} | ||
|
||
QgsGeometry* geometry = feature.geometry(); | ||
if ( geometry ) | ||
{ | ||
// geometry type may be probably different from provider type (e.g. multi x single) | ||
QGis::WkbType geometryType = QGis::flatType( geometry->wkbType() ); | ||
if ( !isPolygon ) | ||
{ | ||
Vect_reset_cats( cats ); | ||
Vect_cat_set( cats, 1, ( int )feature.id() ); | ||
} | ||
|
||
if ( geometryType == QGis::WKBPoint ) | ||
{ | ||
QgsPoint point = geometry->asPoint(); | ||
writePoint( map, GV_POINT, point, cats ); | ||
} | ||
else if ( geometryType == QGis::WKBMultiPoint ) | ||
{ | ||
QgsMultiPoint multiPoint = geometry->asMultiPoint(); | ||
foreach ( QgsPoint point, multiPoint ) | ||
{ | ||
writePoint( map, GV_POINT, point, cats ); | ||
} | ||
} | ||
else if ( geometryType == QGis::WKBLineString ) | ||
{ | ||
QgsPolyline polyline = geometry->asPolyline(); | ||
writePolyline( map, GV_LINE, polyline, cats ); | ||
} | ||
else if ( geometryType == QGis::WKBMultiLineString ) | ||
{ | ||
QgsMultiPolyline multiPolyline = geometry->asMultiPolyline(); | ||
foreach ( QgsPolyline polyline, multiPolyline ) | ||
{ | ||
writePolyline( map, GV_LINE, polyline, cats ); | ||
} | ||
} | ||
else if ( geometryType == QGis::WKBPolygon ) | ||
{ | ||
QgsPolygon polygon = geometry->asPolygon(); | ||
foreach ( QgsPolyline polyline, polygon ) | ||
{ | ||
writePolyline( map, GV_BOUNDARY, polyline, cats ); | ||
} | ||
} | ||
else if ( geometryType == QGis::WKBMultiPolygon ) | ||
{ | ||
QgsMultiPolygon multiPolygon = geometry->asMultiPolygon(); | ||
foreach ( QgsPolygon polygon, multiPolygon ) | ||
{ | ||
foreach ( QgsPolyline polyline, polygon ) | ||
{ | ||
writePolyline( map, GV_BOUNDARY, polyline, cats ); | ||
} | ||
} | ||
} | ||
else | ||
{ | ||
G_fatal_error( "Geometry type not supported" ); | ||
} | ||
|
||
QgsAttributes attributes = feature.attributes(); | ||
attributes.insert( 0, QVariant( feature.id() ) ); | ||
try | ||
{ | ||
QgsGrass::insertRow( driver, QString( fieldInfo->table ), attributes ); | ||
} | ||
catch ( QgsGrass::Exception &e ) | ||
{ | ||
G_fatal_error( "Cannot insert: %s", e.what() ); | ||
} | ||
} | ||
featureCount++; | ||
} | ||
|
||
if ( isPolygon ) | ||
{ | ||
double snapTreshold = 0; | ||
Vect_build_partial( map, GV_BUILD_BASE ); | ||
|
||
if ( snapTreshold > 0 ) | ||
{ | ||
Vect_snap_lines( map, GV_BOUNDARY, snapTreshold, NULL ); | ||
} | ||
Vect_break_polygons( map, GV_BOUNDARY, NULL ); | ||
Vect_remove_duplicates( map, GV_BOUNDARY | GV_CENTROID, NULL ); | ||
while ( true ) | ||
{ | ||
Vect_break_lines( map, GV_BOUNDARY, NULL ); | ||
Vect_remove_duplicates( map, GV_BOUNDARY, NULL ); | ||
if ( Vect_clean_small_angles_at_nodes( map, GV_BOUNDARY, NULL ) == 0 ) | ||
{ | ||
break; | ||
} | ||
} | ||
Vect_merge_lines( map, GV_BOUNDARY, NULL, NULL ); | ||
#if GRASS_VERSION_MAJOR < 7 | ||
Vect_remove_bridges( map, NULL ); | ||
#else | ||
int linesRemoved, bridgesRemoved; | ||
Vect_remove_bridges( map, NULL, &linesRemoved, &bridgesRemoved ); | ||
#endif | ||
Vect_build_partial( map, GV_BUILD_ATTACH_ISLES ); | ||
|
||
QMap<QgsFeatureId, QgsFeature> centroids; | ||
QgsSpatialIndex spatialIndex; | ||
int nAreas = Vect_get_num_areas( map ); | ||
for ( int area = 1; area <= nAreas; area++ ) | ||
{ | ||
double x, y; | ||
if ( Vect_get_point_in_area( map, area, &x, &y ) < 0 ) | ||
{ | ||
// TODO: send warning | ||
continue; | ||
} | ||
QgsPoint point( x, y ); | ||
QgsFeature feature( area ); | ||
feature.setGeometry( QgsGeometry::fromPoint( point ) ); | ||
feature.setValid( true ); | ||
centroids.insert( area, feature ); | ||
spatialIndex.insertFeature( feature ); | ||
} | ||
// read once more to assign centroids to polygons | ||
while ( true ) | ||
{ | ||
stdinStream >> feature; | ||
if ( !feature.isValid() ) | ||
{ | ||
break; | ||
} | ||
if ( !feature.geometry() ) | ||
{ | ||
continue; | ||
} | ||
|
||
QList<QgsFeatureId> idList = spatialIndex.intersects( feature.geometry()->boundingBox() ); | ||
foreach ( QgsFeatureId id, idList ) | ||
{ | ||
QgsFeature& centroid = centroids[id]; | ||
if ( feature.geometry()->contains( centroid.geometry() ) ) | ||
{ | ||
centroid.attributes().append( feature.id() ); | ||
} | ||
} | ||
} | ||
|
||
Vect_copy_map_lines( &tmpMap, &finalMap ); | ||
Vect_close( &tmpMap ); | ||
Vect_delete( tmpName.toUtf8().data() ); | ||
|
||
foreach ( QgsFeature centroid, centroids.values() ) | ||
{ | ||
QgsPoint point = centroid.geometry()->asPoint(); | ||
|
||
if ( centroid.attributes().size() > 0 ) | ||
{ | ||
Vect_reset_cats( cats ); | ||
foreach ( QVariant attribute, centroid.attributes() ) | ||
{ | ||
Vect_cat_set( cats, 1, attribute.toInt() ); | ||
} | ||
writePoint( &finalMap, GV_CENTROID, point, cats ); | ||
} | ||
} | ||
} | ||
|
||
db_close_database_shutdown_driver( driver ); | ||
Vect_build( &finalMap ); | ||
Vect_close( &finalMap ); | ||
|
||
stdoutStream << ( bool )true; // to keep caller waiting until finished | ||
// TODO history | ||
|
||
exit( EXIT_SUCCESS ); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters