Hello, I've been working on setting up mapnik with java through jni so that I can render the openstreetmap data. I've compiled mapnik using the scons build system successfully, and have run the demo code with no issues.
I then wrote a c++ program (1 main method) that renders a specific part of england (I imported only the data for england due to system restraints). The program runs and generates the image as expected. I've attached the source code below (request_tiles.cpp). I then change the method from a main method to a jni method (request_tiles_jni.cpp), wrote the java method (MapnikNative.java), and generated the h file (request_tiles_jni.h). I compile the java using jdk1.6.0_14 (64 bit) then run the method. It breaks with the following error when it tries to register the data sources: /home/ljesper/jdk1.6.0_14/bin/java: symbol lookup error: /home/ljesper/bins/mapnik/lib64/mapnik/input/osm.input: undefined symbol: _ZN7icu_4_213UnicodeStringC1ERKS0_ after ignoring these non-fatal errors: /home/ljesper/bins/mapnik/lib64/mapnik/input/raster.input: undefined symbol: _ZN5boost6system19get_system_categoryEv /home/ljesper/bins/mapnik/lib64/mapnik/input/postgis.input: undefined symbol: _ZN5boost21thread_resource_errorD1Ev /home/ljesper/bins/mapnik/lib64/mapnik/input/shape.input: undefined symbol: _ZN5boost6system19get_system_categoryEv I compile my library with the following command: g++ -o libmapnikjni.o -c -fPIC -DHAVE_LIBXML2 -ansi -Wall -pthread -ftemplate-depth-100 -DLINUX -DBOOST_SPIRIT_THREADSAFE -DMAPNIK_THREADSAFE -O0 -fno-inline -g -DDEBUG -DMAPNIK_DEBUG -DNone -Iagg/include -Iinclude -I. -I/home/ljesper/jdk1.6.0_14/include -I/home/ljesper/jdk1.6.0_14/include/linux -I/usr/include -I/usr/include -I/usr/local/include -I/usr/include/freetype2 -I/usr/include/libxml2 MapnikNative.cpp g++ -o libmapnikjni.so libmapnikjni.o -Lagg -Lsrc -L/usr/lib64 -L/usr/local/lib64 -lboost_thread-gcc34-mt -lmapnik -shared -fPIC I ran ldd on libmapnikjni.so and it found all the dependencies in paths included in the LD_LIBRARY_PATH variable and also printed as part of java.library.path. The methods it prints as undefined are marked as such when I run "nm libmapnikjni.so". The method it breaks on does not appear anywhere in libmapnikjni.so; however, it does appear in libicuuc.so, an included library. My system is a 64bit CentOS 5. My compiler is g++ 3.4.6. I have also followed the same procedure to the same effect on a Debian system with g++ (Debian 4.3.3-10). I am running mapnik 0.6 on both with icu 42. I attached my config.py file just in case that helps. Any suggestions or hunches would be greatly appreciated. Thanks, ldj
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <mapnik/map.hpp>
#include <mapnik/load_map.hpp>
#include <mapnik/projection.hpp>
#include <mapnik/coord.hpp>
#include <stdio.h>
#include <mapnik/graphics.hpp>
#include <mapnik/image_data.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/agg_renderer.hpp>
#include <mapnik/datasource_cache.hpp>
#include <boost/filesystem/operations.hpp>
int main(int argc, char* argv[])
{
int zoom = 10;
double west = -2.7632;
double east = -2.6315;
double south = 53.7336;
double north = 53.7931;
char mapfile[42] = "/home/ljesper/mapnik_0_6_0/mapnik/osm.xml";
double latlong[4] = {west,south,east,north};
int imageWidth = 256;
int imageHeight = 256;
mapnik::datasource_cache::instance()->register_datasources("/home/ljesper/bins/mapnik/lib64/mapnik/input");
mapnik::freetype_engine::register_font("/home/ljesper/bins/mapnik/lib64/mapnik/fonts/DejaVuSans.ttf");
mapnik::Map map = mapnik::Map::Map(imageWidth,imageHeight);
mapnik::load_map(map,mapfile);
mapnik::projection prj = mapnik::projection::projection("+proj=merc
+a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m
+nadgri...@null +no_defs +over");
prj.forward(latlong[0],latlong[1]);
prj.forward(latlong[2],latlong[3]);
mapnik::Envelope<double> box =
mapnik::Envelope<double>::Envelope(latlong[0],latlong[1],latlong[2],latlong[3]);
map.zoomToBox(box);
mapnik::Image32 img = mapnik::Image32::Image32(imageWidth,imageHeight);
mapnik::agg_renderer<mapnik::Image32> render(map,img);
render.apply();
char name[71];
sprintf(name,"/tmp/mapnik_%.9f_%.9f_%.9f_%.9f.png",west,east,south,north);
mapnik::save_to_file(img.data(),name,"png");
int fd = open(name, O_RDWR);
int count = 0;
int size = boost::filesystem::file_size(name);
char result[size];
while ( read(fd, result+count,1) != 0)
{
count++;
}
printf("Function Complete,%d\n",size);
return 0;
}/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_palantir_gis_tiles_source_impl_MapnikNative */
#ifndef _Included_com_palantir_gis_tiles_source_impl_MapnikNative
#define _Included_com_palantir_gis_tiles_source_impl_MapnikNative
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_palantir_gis_tiles_source_impl_MapnikNative
* Method: render
* Signature: (DDDD)[B
*/
JNIEXPORT jbyteArray JNICALL
Java_com_palantir_gis_tiles_source_impl_MapnikNative_render
(JNIEnv *, jclass, jdouble, jdouble, jdouble, jdouble);
#ifdef __cplusplus
}
#endif
#endif#include <jni.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <mapnik/map.hpp>
#include <mapnik/load_map.hpp>
#include <mapnik/projection.hpp>
#include <mapnik/coord.hpp>
#include <stdio.h>
#include <mapnik/graphics.hpp>
#include <mapnik/image_data.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/agg_renderer.hpp>
#include <mapnik/datasource_cache.hpp>
#include <boost/filesystem/operations.hpp>
#include "request_tiles_jni.h"
JNIEXPORT jbyteArray JNICALL
Java_com_palantir_gis_tiles_source_impl_MapnikNative_render
(JNIEnv * env, jclass cla, jdouble w, jdouble e, jdouble s, jdouble n)
{
double west = w;
double east = e;
double south = s;
double north = n;
char mapfile[] = "/home/ljesper/mapnik_0_6_0/mapnik/osm.xml";
double latlong[4] = {west,south,east,north};
int imageWidth = 256;
int imageHeight = 256;
//mapnik::datasource_cache::instance()->register_datasources("/home/ljesper/bins/mapnik/lib64/mapnik/input");
mapnik::freetype_engine::register_font("/home/ljesper/bins/mapnik/lib64/mapnik/fonts/DejaVuSans.ttf");
mapnik::Map map = mapnik::Map::Map(imageWidth,imageHeight);
mapnik::load_map(map,mapfile);
mapnik::projection prj = mapnik::projection::projection("+proj=merc
+a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m
+nadgri...@null +no_defs +over");
prj.forward(latlong[0],latlong[1]);
prj.forward(latlong[2],latlong[3]);
mapnik::Envelope<double> box =
mapnik::Envelope<double>::Envelope(latlong[0],latlong[1],latlong[2],latlong[3]);
map.zoomToBox(box);
mapnik::Image32 buf = mapnik::Image32::Image32(imageWidth,imageHeight);
mapnik::agg_renderer<mapnik::Image32> render(map,buf);
render.apply();
char name[71];
sprintf(name,"/tmp/mapnik_%.9f_%.9f_%.9f_%.9f.png",west,east,south,north);
mapnik::save_as_png(buf.data(), name);
int fd = open(name, O_RDWR);
int count = 0;
int size = boost::filesystem::file_size(name);
char result[size];
while ( read(fd, result+count,1) != 0)
{
count++;
}
jbyteArray jb = env->NewByteArray(count);
env->SetByteArrayRegion(jb, 0, count, (jbyte*)result);
printf("Function Complete\n");
return (jb);
}
MapnikNative.java
Description: /
OPTIMIZATION = '0' DEBUG = True INPUT_PLUGINS = 'gdal,occi,ogr,osm,postgis,raster,shape,sqlite' PREFIX = 'mapnik' PYTHON_PREFIX = 'mapnikpython' DESTDIR = '/home/ljesper/bins' BOOST_INCLUDES = '/usr/include/' BOOST_LIBS = '/usr/lib64/' BOOST_TOOLKIT = 'gcc34' ICU_INCLUDES = '/home/ljesper/icu/source/include' ICU_LIBS = '/home/ljesper/icu/source/lib' BINDINGS = 'none' DEMO = True CAIRO = False
_______________________________________________ Mapnik-devel mailing list [email protected] https://lists.berlios.de/mailman/listinfo/mapnik-devel
