586
598
db_init_string(&strval);
588
600
/* open output vector */
601
/* open temporary vector, do the work in the temporary vector
602
* at the end copy alive lines to output vector
603
* in case of polygons this reduces the coor file size by a factor of 2 to 5
604
* only needed for polygons, but the presence of polygons can be detected
605
* only during OGR feature import, not before */
606
sprintf(buf, "%s", out_opt->answer);
607
/* strip any @mapset from vector output name */
608
G_find_vector(buf, G_mapset());
609
sprintf(tempvect, "%s_tmp", buf);
610
G_verbose_message(_("Using temporary vector <%s>"), tempvect);
611
if (z_flag->answer) {
590
612
Vect_open_new(&Map, out_opt->answer, 1);
613
Vect_open_new(&Tmp, tempvect, 1);
592
616
Vect_open_new(&Map, out_opt->answer, 0);
617
Vect_open_new(&Tmp, tempvect, 0);
594
620
Vect_hist_command(&Map);
784
810
OGR_L_ResetReading(Ogr_layer);
785
G_important_message(_("Importing map %d features..."),
786
OGR_L_GetFeatureCount(Ogr_layer, 1));
811
unsigned int n_features = 0, feature_count = 0;
813
n_polygon_boundaries = 0;
814
n_features = OGR_L_GetFeatureCount(Ogr_layer, 1);
816
/* estimate distance for boundary splitting --> */
818
if (split_distance > -0.5) {
819
/* count polygons and isles */
820
G_message(_("Counting polygons for %d features..."), n_features);
821
while ((Ogr_feature = OGR_L_GetNextFeature(Ogr_layer)) != NULL) {
822
G_percent(feature_count++, n_features, 1); /* show something happens */
824
Ogr_geometry = OGR_F_GetGeometryRef(Ogr_feature);
825
if (Ogr_geometry != NULL) {
826
poly_count(Ogr_geometry);
828
OGR_F_Destroy(Ogr_feature);
831
OGR_L_ResetReading(Ogr_layer);
835
G_debug(1, "n polygon boundaries: %d", n_polygon_boundaries);
836
if (split_distance > -0.5 && n_polygon_boundaries > 50) {
838
area_size / log(n_polygon_boundaries);
839
/* divisor is the handle: increase divisor to decrease split_distance */
840
split_distance = split_distance / 4.;
841
G_debug(1, "root of area size: %f", area_size);
842
G_verbose_message(_("Boundary splitting distance in map units: %G"),
845
/* <-- estimate distance for boundary splitting */
847
G_important_message(_("Importing map %d features..."), n_features);
787
848
while ((Ogr_feature = OGR_L_GetNextFeature(Ogr_layer)) != NULL) {
849
G_percent(feature_count++, n_features, 1); /* show something happens */
789
851
Ogr_geometry = OGR_F_GetGeometryRef(Ogr_feature);
790
852
if (Ogr_geometry == NULL) {
902
966
G_message("%s", separator);
903
967
G_warning(_("Cleaning polygons, result is not guaranteed!"));
905
Vect_set_release_support(&Map);
907
Vect_open_update(&Map, out_opt->answer, G_mapset());
908
Vect_build_partial(&Map, GV_BUILD_BASE); /* Downgrade topo */
911
970
G_message("%s", separator);
912
971
G_message(_("Snap boundaries (threshold = %.3e):"), snap);
913
Vect_snap_lines(&Map, GV_BOUNDARY, snap, NULL);
972
Vect_snap_lines(&Tmp, GV_BOUNDARY, snap, NULL);
916
975
/* It is not to clean to snap centroids, but I have seen data with 2 duplicate polygons
925
984
G_message("%s", separator);
926
985
G_message(_("Break polygons:"));
927
Vect_break_polygons(&Map, GV_BOUNDARY, NULL);
986
Vect_break_polygons(&Tmp, GV_BOUNDARY, NULL);
929
/* It is important to remove also duplicate centroids in case of duplicate imput polygons */
988
/* It is important to remove also duplicate centroids in case of duplicate input polygons */
930
989
G_message("%s", separator);
931
990
G_message(_("Remove duplicates:"));
932
Vect_remove_duplicates(&Map, GV_BOUNDARY | GV_CENTROID, NULL);
991
Vect_remove_duplicates(&Tmp, GV_BOUNDARY | GV_CENTROID, NULL);
993
/* split boundaries here ? */
934
995
/* Vect_clean_small_angles_at_nodes() can change the geometry so that new intersections
935
996
* are created. We must call Vect_break_lines(), Vect_remove_duplicates()
936
* and Vect_clean_small_angles_at_nodes() until no more small dangles are found */
997
* and Vect_clean_small_angles_at_nodes() until no more small angles are found */
938
999
G_message("%s", separator);
939
1000
G_message(_("Break boundaries:"));
940
Vect_break_lines(&Map, GV_BOUNDARY, NULL);
1001
Vect_break_lines(&Tmp, GV_BOUNDARY, NULL);
942
1003
G_message("%s", separator);
943
1004
G_message(_("Remove duplicates:"));
944
Vect_remove_duplicates(&Map, GV_BOUNDARY, NULL);
1005
Vect_remove_duplicates(&Tmp, GV_BOUNDARY, NULL);
946
1007
G_message("%s", separator);
947
1008
G_message(_("Clean boundaries at nodes:"));
949
Vect_clean_small_angles_at_nodes(&Map, GV_BOUNDARY, NULL);
1010
Vect_clean_small_angles_at_nodes(&Tmp, GV_BOUNDARY, NULL);
950
1011
} while (nmodif > 0);
952
1013
G_message("%s", separator);
953
1014
if (type & GV_BOUNDARY) { /* that means lines were converted boundaries */
954
1015
G_message(_("Change boundary dangles to lines:"));
955
Vect_chtype_dangles(&Map, -1.0, NULL);
1016
Vect_chtype_dangles(&Tmp, -1.0, NULL);
958
1019
G_message(_("Change dangles to lines:"));
959
Vect_remove_dangles(&Map, GV_BOUNDARY, -1.0, NULL);
1020
Vect_remove_dangles(&Tmp, GV_BOUNDARY, -1.0, NULL);
962
1023
G_message("%s", separator);
963
1024
if (type & GV_BOUNDARY) {
964
1025
G_message(_("Change boundary bridges to lines:"));
965
Vect_chtype_bridges(&Map, NULL);
1026
Vect_chtype_bridges(&Tmp, NULL);
968
1029
G_message(_("Remove bridges:"));
969
Vect_remove_bridges(&Map, NULL);
1030
Vect_remove_bridges(&Tmp, NULL);
1033
/* merge boundaries */
1034
G_message("%s", separator);
1035
G_message(_("Merge boundaries:"));
1036
Vect_merge_lines(&Tmp, GV_BOUNDARY, NULL, NULL);
972
1038
/* Boundaries are hopefully clean, build areas */
973
1039
G_message("%s", separator);
974
Vect_build_partial(&Map, GV_BUILD_ATTACH_ISLES);
1040
Vect_build_partial(&Tmp, GV_BUILD_ATTACH_ISLES);
976
1042
/* Calculate new centroids for all areas, centroids have the same id as area */
977
ncentr = Vect_get_num_areas(&Map);
1043
ncentr = Vect_get_num_areas(&Tmp);
978
1044
G_debug(3, "%d centroids/areas", ncentr);
980
1046
Centr = (CENTR *) G_calloc(ncentr + 1, sizeof(CENTR));
1050
1122
otype = GV_POINT;
1052
1124
otype = GV_CENTROID;
1053
Vect_write_line(&Map, otype, Points, Centr[centr].cats);
1125
Vect_write_line(&Tmp, otype, Points, Centr[centr].cats);
1057
G_message("%s", separator);
1058
Vect_build_partial(&Map, GV_BUILD_NONE);
1060
G_message("%s", separator);
1063
G_message("%s", separator);
1130
Vect_spatial_index_destroy(&si);
1132
/* G_message("%s", separator); */
1133
/* Vect_build_partial(&Map, GV_BUILD_NONE); */
1136
/* G_message("%s", separator);
1137
Vect_build(&Map); */
1065
1139
if (n_overlaps > 0) {
1066
1140
G_warning(_("%d areas represent more (overlapping) features, because polygons overlap "
1069
1143
n_overlaps, nlayers + 1);
1072
sprintf(buf, _("%d input polygons"), n_polygons);
1074
Vect_hist_write(&Map, buf);
1076
sprintf(buf, _("Total area: %e (%d areas)"), total_area, ncentr);
1078
Vect_hist_write(&Map, buf);
1080
sprintf(buf, _("Overlapping area: %e (%d areas)"), overlap_area,
1146
G_message("%s", separator);
1148
Vect_hist_write(&Map, separator);
1149
Vect_hist_write(&Map, "\n");
1150
sprintf(buf, _("%d input polygons\n"), n_polygons);
1151
G_message(_("%d input polygons"), n_polygons);
1152
Vect_hist_write(&Map, buf);
1154
sprintf(buf, _("Total area: %G (%d areas)\n"), total_area, ncentr);
1155
G_message(_("Total area: %G (%d areas)"), total_area, ncentr);
1156
Vect_hist_write(&Map, buf);
1158
sprintf(buf, _("Overlapping area: %G (%d areas)\n"), overlap_area,
1160
G_message(_("Overlapping area: %G (%d areas)"), overlap_area,
1083
1162
Vect_hist_write(&Map, buf);
1085
sprintf(buf, _("Area without category: %e (%d areas)"), nocat_area,
1164
sprintf(buf, _("Area without category: %G (%d areas)\n"), nocat_area,
1166
G_message(_("Area without category: %G (%d areas)"), nocat_area,
1088
1168
Vect_hist_write(&Map, buf);
1169
G_message("%s", separator);
1092
1173
* OGR_DS_Destroy( Ogr_ds );
1176
/* Copy temporary vector to output vector */
1177
Vect_copy_map_lines(&Tmp, &Map);
1179
Vect_delete(tempvect);
1095
1182
Vect_close(&Map);