calvinmetcalf / shapefile-js

Convert a Shapefile to GeoJSON. Not many caveats.
http://calvinmetcalf.github.io/shapefile-js/
715 stars 228 forks source link

proj4 module resolution/usage confused #75

Closed estaub closed 7 years ago

estaub commented 7 years ago

In an npm/webpack build, I cannot use shapefile-js. It appears that the proj4 module is not resolved correctly; shapefile-js throws with proj4 is not a function.

On line 57 of index.js, zip[key.slice(0, -3) + key.slice(-3).toLowerCase()] = proj4(zip[key]); should maybe be: zip[key.slice(0, -3) + key.slice(-3).toLowerCase()] = proj4.default(zip[key]);

This works for me, but maybe it breaks some other build-tooling scenario. I've never seen this kind of problem before with published code.

If you need a "prj" shapefile to test against, grab a census shapefile from https://www.census.gov/geo/maps-data/data/cbf/cbf_sld.html .

calvinmetcalf commented 7 years ago

this is a commonjs module not an es6 module, I think you have your web pack settings wrong

estaub commented 7 years ago

Note (if not obvious) that this is not a problem with importing shapefile-js; that import is correct. It's the internal import of proj4 that's messed up.

I'm not doing anything special in my webpack config for module resolution. I have dozens of dependencies, many of which are CommonJS, without problem. But I'm out of my depth in trying to understand what's wrong in this case, especially in studying proj4. The problem occurs with both Webpack 1 and 2. Time will tell; if you get another report like this, please consider looking into it further.

Is it at all possible that I'm the only person using prj shapefiles with webpack?

This may actually turn out to be a proj4 issue; if so, please talk to the author ;-)

calvinmetcalf commented 7 years ago

I'm the author of both

proj4 uses rollup under the hood and exports a es6 module version to those wanting es6 modules but a regular commonjs version for those (like this module) that want commonjs.

it would seem that webpack is for some reason requesting the es6 version on behalf of this module even though this module doesn't want it

estaub commented 7 years ago

I ran across this, FWIW. I can't tell whether it's on point or not. It's close. https://github.com/webpack/webpack/issues/706

calvinmetcalf commented 7 years ago

are you transpiling your dependencies per chance ?

estaub commented 7 years ago

are you transpiling your dependencies per chance ?

Nope - except for the normal require processing webpack does during bundling.

pawanmalik commented 7 years ago

I am getting the same issue as estaub has described above. Any zip file which contains a ".prj" file fails with the following error: "TypeError: proj4 is not a function at Function.shp.parseZip".

I am using webpack 2 with Angular 2. Here is my tsconfig.json file: { "compilerOptions": { "target": "es5", "module": "commonjs", "moduleResolution": "node", "sourceMap": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "removeComments": false, "noImplicitAny": false, "typeRoots": [ "../node_modules/@types" ] }, "exclude": [ "node_modules" ] }

Any pointers on what could be the issue?

estaub commented 7 years ago

@pawanmalik FWIW, I've continued to use a patched copy with .default added with good success. Long-term I intend to find another solution (convert to GeoJSON once on server, and serve GeoJSON gzipped), but it works for now. This project, with all its dependencies, is very large - not suitable for most browser production uses where there's another option.

pawanmalik commented 7 years ago

@estaub can you please illustrate how you are using .default? I am facing another issue with "prj" files: "TypeError: trans.inverse is not a function at ParseShp.eval [as parseCoord]"

Did you come across this error as well?

calvinmetcalf commented 7 years ago

ok so the gist of it is that proj4 recently switched to rollup and for some reason webpack is now trying to treat it as a es6 style module instead of as a commonjs module even though it's set up to be exported as one

estaub commented 7 years ago

@pawanmalik I didn't come across your problem, but (without looking) I'd guess that it's just a matter of what's in the shapefile driving different symptoms.

As for how I'm using .default: I cloned a copy of shapefile-js, made the change in my first post on line 57, and am using the clone. I should have forked, but I was a git noob at the time. In config.json, use a "file:" url to refer to your patched version. I don't recommend doing this in general, of course, but if you're as desperate as I was it may be worth doing. The problem probably occurs at all imports from proj4 in shapefile-js; I didn't look for others as this was all it took for me. A better approach than fixing it where I did is to fix it (add a .default) on the import (require()) line.

pawanmalik commented 7 years ago

@estaub Thanks for the explanation.

venikx commented 6 years ago

@pawanmalik @estaub Hello, I'm very very new to the Geo world and I'm having troubles with converting the zipped shapefiles to geoJSON. I was wondering how you peeps have solved the importing issue, because I'm getting the same error.

error TypeError: proj4 is not a function
    at Function.webpackJsonp.../../../../shpjs/lib/index.js.shp.parseZip (index.js:72)
    at index.js:134
    at tryToUnwrap (browser.js:146)
    at tryCatch (browser.js:158)
    at safelyResolveThenable (browser.js:149)
    at new Promise (browser.js:23)
    at Function.webpackJsonp.../../../../shpjs/lib/index.js.shp.getShapefile (index.js:133)
    at shp (index.js:35)
    at SwitchMapSubscriber.project (file-upload.ts:44)
    at SwitchMapSubscriber.webpackJsonp.../../../../rxjs/operator/switchMap.js.SwitchMapSubscriber._next (switchMap.js:88)