Giter VIP home page Giter VIP logo

cleangeo's Introduction

cleangeo

CRAN_Status_Badge Github_Status_Badge cran checks DOI

cleangeo provides utilities to clean geometries from spatial objects in R. If you aim to do geoprocessing in R, this package will help you in cleaning your Spatial* objects before, and avoid geoprocessing errors later.

Note on cleangeo archiving process (after version 0.3), needs/prerequisites to move to sf

The_ cleangeo package was developed in 2015 at at time where sp and rgeos, maptools, raster, etc. were among R solutions to deal with spatial data handling. With the increase of sf instead of sp objects, it's recommended to switch progressively to sf as base for handling spatial features, and to use sf::st_make_valid to validate geometries (which is now the default in cleangeo). Following the archiving of rgeos, maptools, it is probable that cleangeo may also be archived.

Native geometry fixing strategies, although applicable in some cases, do not cover the full typology of geometry issues we may find with vector data. Although refactored to remove the dependency with rgeos and maptools, some unexpected behaviors can be found.

With the progress done on validating geometries, especially with sf, the default strategy to fix geometries in cleangeo has now been switched to the use of sf::st_make_valid.

Nonetheless, although the original set-up and actual name of sf refers to an ISO/OGC specification (Simple Features), users that handle geospatial data with tools that rely on the ISO/OGC realm (most of GIS tools, from the OsGeo or even proprietary software) should use sf cautiously as the default behavior doesn't rely anymore on the ISO/OGC realm for managing geographic coordinates (it was initially) but on a non-standard technology-specific geometry model handled with s2 (from the name of the library developed by Google). To turn off this default set-up, and to conserve legacy behaviors (backward-compatibility) in geospatial processes, users will need to ensure they use sf::sf_use_s2(FALSE). This is particularly needed if you grab data from OGC data services (eg. with ows4R), and related OGC formats that do not rely on the s2 data model, but on the ISO/OGC Simple Features data model.

Citation

We thank in advance people that use cleangeo for citing it in their work / publication(s). For this, please use the citation provided at this link DOI

Use cases

Some projects using cleangeo:

cleangeo's People

Contributors

eblondel avatar kendonb 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Forkers

cjtexas kendonb

cleangeo's Issues

Error with NULL polygons during cleaning

I used R to convert a publicly-available .kml file to .shp. Then I imported it into R with readOGR(). I ran clgeo_Clean() with verbose = TRUE and after a time it threw:

Error in slot(x, "coords") : 
  cannot get a slot ("coords") from an object of type "NULL"

with traceback() output:

12: slot(x, "coords")
11: FUN(X[[i]], ...)
10: lapply(po, function(x) {
        outpo <- x
        coords <- slot(x, "coords")
        coords[, 1] <- as.character(coords[, 1])
        coords[, 2] <- as.character(coords[, 2])
        if (nrow(unique(slot(x, "coords"))) < 3) 
            outpo <- NULL
        return(outpo)
    })
9: FUN(X[[i]], ...)
8: lapply(1:length(holes), function(i) {
       hole <- holes[[i]]
       temphole <- SpatialPolygons(Srl = list(Polygons(srl = list(hole), 
           ID = "1")))
       po <- hole
       isValid <- clgeo_IsValid(temphole, verbose)
       if (!isValid) {
           po <- clgeo_CleanByPolygonation.Polygon(hole, verbose)
       }
       if (!is.list(po)) 
           po <- list(po)
       po <- lapply(po, function(x) {
           outpo <- x
           coords <- slot(x, "coords")
           coords[, 1] <- as.character(coords[, 1])
           coords[, 2] <- as.character(coords[, 2])
           if (nrow(unique(slot(x, "coords"))) < 3) 
               outpo <- NULL
           return(outpo)
       })
       po <- po[!sapply(po, is.null)]
       out <- NULL
       if (!is.null(po) && length(po) > 0) {
           if (!is.list(po)) 
               po <- list(po)
           polyholes <- Polygons(srl = po, ID = as.character(ID))
           if (slot(polyholes, "area") > 0) 
               out <- polyholes
           if (!is.null(out)) {
               if (slot(polyholes, "area") >= (1/rgeos::getScale())) {
                   ID <<- ID + 1
               }
               else {
                   out <- NULL
               }
           }
       }
       return(out)
   })
7: FUN(X[[i]], ...)
6: lapply(sp@polygons, clgeo_CleanByPolygonation.Polygons, verbose)
5: unlist(lapply(sp@polygons, clgeo_CleanByPolygonation.Polygons, 
       verbose))
4: clgeo_CleanByPolygonation.SpatialPolygons(polygon, verbose)
3: FUN(X[[i]], ...)
2: lapply(1:length(sp), function(x) {
       polygon <- slot(sp, "polygons")[[x]]
       ID <- slot(polygon, "ID")
       if (!all(is.na(nv))) {
           if (x %in% nv) {
               polygons <- slot(polygon, "Polygons")
               poly.nb <- length(polygons)
               removedHoles <- vector()
               if (poly.nb > 0) {
                   newpolygons <- list()
                   for (i in 1:poly.nb) {
                     if (slot(polygons[[i]], "hole")) {
                       if (dim(unique(slot(polygons[[i]], "coords")))[1] < 
                         3) {
                         if (length(removedHoles) == 0 & verbose) {
                           logger.info(sprintf("Cleaning orphaned holes at index %s", 
                             x))
                         }
                         removedHoles <- c(removedHoles, i)
                       }
                       else {
                         newpolygon <- polygons[[i]]
                         slot(newpolygon, "hole") <- TRUE
                         newpolygons <- c(newpolygons, newpolygon)
                       }
                     }
                     else {
                       newpolygon <- polygons[[i]]
                       slot(newpolygon, "hole") <- FALSE
                       newpolygons <- c(newpolygons, newpolygon)
                     }
                   }
                   slot(polygon, "Polygons") <- newpolygons
               }
               polygon <- SpatialPolygons(Srl = list(polygon))
               isValid <- report[x, ]$valid
               if (length(removedHoles) > 0) {
                   if (verbose) {
                     logger.info(sprintf("Checking geometry validity at index %s", 
                       x))
                   }
                   tryCatch({
                     slot(polygon, "polygons") <<- lapply(slot(polygon, 
                       "polygons"), checkPolygonsHoles)
                   }, warning = function(msg) {
                     if (verbose) 
                       logger.info(sprintf("Catched MAPTOOLS warning '%s'", 
                         msg))
                   }, error = function(err) {
                     if (verbose) 
                       logger.info(sprintf("Catched MAPTOOLS error '%s'", 
                         err))
                   })
                   isValid <<- clgeo_IsValid(polygon, verbose)
               }
               if (is.null(errors.only) & !isValid) {
                   if (verbose) {
                     report.msg <- NULL
                     if (!is.na(report[x, "error_msg"])) {
                       report.msg <- report[x, "error_msg"]
                     }
                     else if (!is.na(report[x, "warning_msg"])) {
                       report.msg <- report[x, "warning_msg"]
                     }
                     logger.info(sprintf("Cleaning geometry at index %s (%s)", 
                       x, report.msg))
                   }
                   if (strategy == "POLYGONATION") {
                     polygon <- clgeo_CleanByPolygonation.SpatialPolygons(polygon, 
                       verbose)
                   }
                   else if (strategy == "BUFFER") {
                     attempt <- 1
                     polygon <- gBuffer(polygon, id = ID, width = 0)
                     while (attempt < 3) {
                       if (!clgeo_IsValid(polygon, verbose)) {
                         attempt <- attempt + 1
                         polygon <- gBuffer(polygon, id = ID, width = 0)
                       }
                       else {
                         break
                       }
                     }
                   }
               }
               if (!is.null(polygon)) {
                   polygon <- polygon@polygons[[1]]
                   slot(polygon, "ID") <- ID
               }
               else {
                   if (verbose) {
                     logger.info(sprintf("Removing false polygon at index %s", 
                       x))
                   }
               }
           }
       }
       return(polygon)
   })
1: clgeo_Clean(asentamiento.shp.orig, verbose = TRUE)

I will email @eblondel the file.

Improve cleaning log statements

  • add convenience cleangeo logger based on cat (not print)
  • make cleaning geometry statement more evident (add the validity report info)
  • suppress warnings of geometry validity if verbose = FALSE

Error in clgeo_Clean

Hi Emmanuel,
I came across your package when recently cleaning spatial polygons data that I derived from GADM (downloaded as .rds):

path <- your_path # adjust
test.0 <- getData("GADM", country="KEN", level=1, path=path)
clgeo_CollectionReport(test.0)
test.clean <- clgeo_Clean(test.0)

  Error in RGEOSBinTopoFunc(spgeom1, spgeom2, byid, id, drop_lower_td, "rgeos_difference") : 
  TopologyException: Input geom 0 is invalid: Nested shells at or near point 37.309135439999999   
  -0.14862486999999999 at 37.309135439999999 -0.14862486999999999

But this worked:

  test.1 <- getData("GADM", country="DEU", level=1, path=path)
  clgeo_CollectionReport(test.1)
  test.clean.1 <- clgeo_Clean(test.1)

Thanks for putting this package together!

Changes from PROJ6 and retirement of rgdal, rgeos, etc. the end of 2023

The supporting packages that appear to be used by CleanGeo have been changing to meet the needs of the PROJ6 upgrades, move away from proj, and the retirement of serveral SP to GDAL interface packages. There are still a lot of dirty shapefiles on the internet ready to take any program out- crash boom. A package like CleanGeo has been a great help to keep these issues in check. However, resently, the rgdal and rgeos package are turnout a lot of error messages and warnings because of the migration away form PROJ4 and the other R packages. Some of their published suggestions work and other do not. I've tried everything to quiet their proclumations and finally had to make modificatons to CleanGeo to continue to run with a reasonable user interface (not scaring them). Not the best solution - would like an updated version of CleanGeo that properly handles the current situation with spatial operations. My modifications were:

  1. adding the package name in front of every function call. (
    sp:SpatialPolygons() ) This appears to be needed to make sure the namespaces and import/exports are done correctly (my guess).
  2. changing slot references from using @ to slot( , "slot") to help R and remove warning/error messages when dealing with projections.

Sincerely, Jim.

The clgeo_Clean function doesn't clean my data

Hello Emmanuel,

I'm trying to make a spatial join between a SpatialPointsDataFrame and a SpatialPolygonsDataFrame (I create this from a SpatialLinesDataFrame, through the functions SpatialLines2PolySet and PolySet2SpatialPolygons). But my Spatial Polygons have some problems (GEOM_VALIDITY and ORPHANED_HOLE), which I can't make the spatial join that I want. I used your package, and the function clgeo_Clean, but it doesn't clean my shape.

My code is the next.

Malla_vial5 <- 
  readShapePoly("Malla_vial3_", proj4string = CRS("+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"), verbose = TRUE, repair= TRUE, delete_null_obj = TRUE, force_ring = TRUE, retrieve_ABS_null = TRUE)

report <- 
      clgeo_CollectionReport(Malla_vial5)
clgeo_SummaryReport(report)
sp.clean <- 
      clgeo_Clean(Malla_vial5, errors.only = "ORPHANED_HOLE")
report.clean <- 
      clgeo_CollectionReport(sp.clean)
clgeo_SummaryReport(report.clean)

However, I can't upload the shape,the system don't support that file type. I have it in dropbox. Could you give your email to share you the fIle?

PD: Thank you for your package, it is the only package that try to fix these problems with the spatial objects.

error with countriesLow

I get this in 0.1-0

library(rworldmap)
data(countriesLow)
library(cleangeo)
x <- clgeo_Clean(countriesLow)
Error in SpatialPolygonsDataFrame(Sr = fixed.sp, data = as(sp, "data.frame")) :
row.names of data and Polygons IDs do not match

Thanks! (I'll explore more when I have a chance).

Handle GEOS exceptions (errors)

Most of geometry validity issues are raised as warnings invoking gIsValid function. In case of errors (essentially due to GEOS exceptions, e.g. IllegalArgumentExceptions), clgeo_Clean stops and returns the GEOS error. To investigate (with data shared in #16)

Error with polygon slot

Hello,

Thank you for this excellent package. In updating from .1-2 to the current version on CRAN (or the dev version, same issue), I now get an error in my batch script. It seems that running spTransform from the sp package prior to running clgeo is what breaks the process, but I do need to perform this transformation so I'm a bit stuck. Running the cleo before the transformation creates other issues. What's strange for me is that reverting to .1-2 removes the problem and it appears to clean the spdf just find. The error message is:

Error in clgeo_CleanByPolygonation.Polygon(polygon) : 
  trying to get slot "polygons" from an object of a basic class ("NULL") with no slots
In addition: There were 38 warnings (use warnings() to see them)

The warnings I get are:

Warning messages:
1: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Too few points in geometry component at or near point -73.487313999999998 42.049638000000002
2: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Self-intersection at or near point -72.847142000000005 42.036893999999997
3: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Self-intersection at or near point -72.816740999999993 41.997594999999997
4: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Self-intersection at or near point -72.606975289999994 42.025240289999999
5: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Self-intersection at or near point -71.890785789999995 42.024368150000001
6: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Self-intersection at or near point -73.521040999999997 41.619773000000002
7: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Self-intersection at or near point -73.516784999999999 41.687581000000002
8: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Ring Self-intersection at or near point -73.501983999999993 41.858716999999999
9: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Self-intersection at or near point -73.489615000000001 42.000091939999997
10: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Ring Self-intersection at or near point -71.582909999999998 42.195559000000003
11: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Self-intersection at or near point -71.574289500000006 42.263660889999997
12: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Self-intersection at or near point -71.597332859999995 42.39463087
13: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Too few points in geometry component at or near point -71.552792400000001 42.433623500000003
14: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Too few points in geometry component at or near point -71.560366999999999 42.474350000000001
15: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Too few points in geometry component at or near point -71.531475999999998 42.520487000000003
16: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Too few points in geometry component at or near point -71.533057600000006 42.525267939999999
17: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Self-intersection at or near point -71.594643000000005 42.543370000000003
18: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Too few points in geometry component at or near point -71.636078999999995 42.539923999999999
19: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Too few points in geometry component at or near point -71.635812000000001 42.524090999999999
20: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Too few points in geometry component at or near point -71.664614 42.611589000000002
21: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Too few points in geometry component at or near point -71.775412790000004 42.638295800000002
22: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Self-intersection at or near point -71.858410000000006 42.633839999999999
23: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Too few points in geometry component at or near point -71.857820000000004 42.674987000000002
24: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Self-intersection at or near point -71.330206000000004 42.697189999999999
25: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Self-intersection at or near point -71.255606090000001 42.736388069999997
26: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Too few points in geometry component at or near point -71.245503999999997 42.742589000000002
27: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Self-intersection at or near point -71.06420104 42.80628901
28: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Too few points in geometry component at or near point -71.335196999999994 41.835500000000003
29: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Too few points in geometry component at or near point -71.338697999999994 41.898398999999998
30: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Too few points in geometry component at or near point -71.381400999999997 42.018797999999997
31: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Too few points in geometry component at or near point -71.778613019999995 44.399799000000002
32: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Too few points in geometry component at or near point -71.749533 44.401955000000001
33: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Self-intersection at or near point -70.848625029999994 42.860939010000003
34: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Self-intersection at or near point -70.96650004 42.868988989999998
35: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Self-intersection at or near point -71.059326839999997 42.818615870000002
36: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Self-intersection at or near point -71.181810409999997 42.737681600000002
37: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Too few points in geometry component at or near point -71.294205000000005 42.69699
38: In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
Self-intersection at or near point -71.636214100000004 42.704887999999997

Running time for clgeo_Clean()

I have executed clgeo_Clean() on a 6MB shapefile (you can download it from here: it's the Reg2011_WGS84 file with all features merged into one, which I renamed Ita2011_WGS84) and is still running after almost 24 hours.

This is my code:

sp <- readShapePoly('Ita2011_WGS84');
report <- clgeo_CollectionReport(sp);
clgeo_SummaryReport(report);
type valid issue_type
rgeos_validity:1 Mode :logical GEOM_VALIDITY:1
FALSE:1
NA's :0
sp.clean <- clgeo_Clean(sp);


Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

Create package structure & import base functions

Base functions include the following utilities:

  • clgeo_GeometryReport: provide a geometry validity report (list)
  • clgeo_CollectionReport: provide a collection validity report (data.frame)
  • clgeo_SuspiciousFeatures: provide the list of indexes of suspicious features (vector)
  • clgeo_Clean: cleans a Spatial* object (at now limited to SpatialPolygons)
  • clgeo_SummaryReport: report summary (table)

Unable to Load cleangeo Library

Dear Emmanuel Blondel,

Thank you for your cleangeo package. In my company, we been using as part of our R code to clean and verified our shapefiles for almost one year. Since the new update, I am having a problem loading the library. I am getting the following problem:

suppressMessages(library(cleangeo)) # for clgeo_Clean
Error in get(Info[i, 1], envir = env) : 
  lazy-load database '/Library/Frameworks/R.framework/Versions/3.3/Resources/library/sp/R/sp.rdb' is corrupt
In addition: Warning message:
In get(Info[i, 1], envir = env) : internal error -3 in R_decompress1
Error: package or namespace load failed for ‘cleangeo’

Can you help me to figure out what is going wrong? I reinstalled without any effect in the problem.

Thak you ahead,
Alex

dependency on retiring spatial infrastructure packages

See #26

You will be aware, for example from:
https://r-spatial.org/r/2022/04/12/evolution.html,
https://r-spatial.org/r/2022/12/14/evolution2.html,
https://r-spatial.org/r/2023/04/10/evolution3.html and
https://rsbivand.github.io/csds_jan23/bivand_csds_ssg_230117.pdf and
perhaps view https://www.youtube.com/watch?v=TlpjIqTPMCA&list=PLzREt6r1NenmWEidssmLm-VO_YmAh4pq9&index=1
that rgdal, rgeos and maptools will be retired this
year, in October 2023.

rgeos::gBuffer rgeos::gCrosses rgeos::gDifference rgeos::getScale rgeos::gIntersection rgeos::gIsValid rgeos::gUnionCascaded are detected by pkgapi, there may be more use. All of these can be worked around by coercing to sf and perhaps using st_make_valid; those GEOS facilities were not available when this package began. s2 is a different question, but also relevant in that here one would have to turn off s2 to keep legacy behaviour, and the default precision in sf differs from rgeos. Action is needed urgently, otherwise this package will be archived when rgeos retires.

Advanced cleaning based on triangulation / polygonation

Hi Emmanuel,
I am back to cleaning polygons and have come across a different method for cleaning them that seems to address the case of bowtie polygons, which lose a lot of area using either 'gBuffer', 'gSimplify' and 'cleangeo' methods. It's called prepair (https://github.com/tudelft3d/prepair) and is only implemented in C++. I'm trying to implement it to do some cleaning by doing system() calls in R. Thought you may like to take a look at it.
Best,
Luke

rgeos warning

Hi again! There's a number of moving parts between the last time I submitted a bug report (new R versions, sp updates, and new versions of your package), but I'm no longer able to clean the same shape file I was working with. It used to complete in seconds, but I'm getting errors such as the following in the verbose output of clgeo_Clean:

[cleangeo][INFO] Catched RGEOS warning 'simpleWarning in RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid"): Ring Self-intersection at or near point -2884367.4982672399 3537417.1548343902
' 
[cleangeo][INFO] Catched RGEOS warning 'simpleWarning in RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid"): Ring Self-intersection at or near point -2258215.72911544 2346387.0472559901
' 

The summary and isValid outout for this shapefile are:

> clgeo_SummaryReport(report)
             type      valid                 issue_type
 rgeos_validity: 8   Mode :logical   GEOM_VALIDITY: 8  
 NA's          :91   FALSE:8         NA's         :91  
                     TRUE :91                          
                     NA's :0                           
> clgeo_IsValid(tec_rx_laea_raw, verbose=TRUE)
[cleangeo][INFO] Catched RGEOS warning 'simpleWarning in RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid"): Ring Self-intersection at or near point -2884367.4982672399 3537417.1548343902
' 
[1] FALSE

Happy to provide you with a copy of the shape file off line if you have time to look at it. Would it be advisable to revert to the "buffer" strategy? With this method it completes in the "normal" amount of time with this output:

[cleangeo][INFO] Cleaning geometry at index 2 (Ring Self-intersection at or near point -2884367.4982672399 3537417.1548343902) 
[cleangeo][INFO] Cleaning geometry at index 18 (Self-intersection at or near point 2113533.1055950201 -820989.46085422998) 
[cleangeo][INFO] Cleaning geometry at index 36 (Self-intersection at or near point 2201242.5476380899 -122464.20489261999) 
[cleangeo][INFO] Cleaning geometry at index 48 (Self-intersection at or near point -663318.71329095995 -1008727.5029289901) 
[cleangeo][INFO] Cleaning geometry at index 51 (Ring Self-intersection at or near point 2305334.6818985799 211472.93414217001) 
[cleangeo][INFO] Cleaning geometry at index 69 (Ring Self-intersection at or near point -764312.57034562004 -1104824.43560423) 
[cleangeo][INFO] Cleaning geometry at index 78 (Self-intersection at or near point 1783130.8072641599 -1814850.07555165) 
[cleangeo][INFO] Cleaning geometry at index 94 (Self-intersection at or near point 795575.92022841994 -1689707.2803640501) 

All the best,
Derek

PS: Possibly of note, this shape file has the following Albers-type CRS:

CRS("+proj=laea +lat_0=45 +lon_0=-100 +x_0=0 +y_0=0 +a=6370997 +b=6370997 +units=m +no_defs")


Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

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.