Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Implementation of RFC 102: Styleitem Javascript with v8 engine
  • Loading branch information
Alan Boudreault committed Sep 26, 2013
1 parent a51a359 commit a966c1c
Show file tree
Hide file tree
Showing 11 changed files with 550 additions and 40 deletions.
17 changes: 16 additions & 1 deletion CMakeLists.txt
Expand Up @@ -201,7 +201,7 @@ mapogcfiltercommon.c maprendering.c mapwcs20.c mapogcsld.c
mapresample.c mapwfs.c mapgdal.c mapogcsos.c mapscale.c mapwfs11.c
mapgeomtransform.c mapogroutput.c mapsde.c mapwfslayer.c mapagg.cpp mapkml.cpp
mapgeomutil.cpp mapkmlrenderer.cpp fontcache.c textlayout.c
mapogr.cpp mapcontour.c mapsmoothing.c ${REGEX_SOURCES})
mapogr.cpp mapcontour.c mapsmoothing.c mapv8.cpp ${REGEX_SOURCES})

if(BUILD_DYNAMIC)
add_library(mapserver SHARED ${mapserver_SOURCES} ${agg_SOURCES})
Expand Down Expand Up @@ -731,6 +731,20 @@ if(WITH_PYTHON)
set(USE_PYTHON_MAPSCRIPT 1)
endif(WITH_PYTHON)

if(WITH_V8)
find_package(V8)
if(V8_FOUND EQUAL 1)
set(USE_V8 1)
include_directories(${V8_INCLUDE})
ms_link_libraries( ${V8_LIBS})
else(V8_FOUND)
message(SEND_ERROR "V8 JavaScript support requested but not found.
HINTS:
- set V8_ROOT environment variable to the installation path of V8.
- add the V8 install directory to the CMAKE_PREFIX_PATH variable (-DCMAKE_PREFIX_PATH=\"/path/to/${component}-install-dir;/path/to/other/dirs\") ")
endif()
endif(WITH_V8)

if(WITH_PHP)
add_subdirectory("mapscript/php")
set(USE_PHP_MAPSCRIPT 1)
Expand Down Expand Up @@ -853,6 +867,7 @@ status_optional_feature("Thread-safety support" "${USE_THREAD}")
status_optional_feature("KML output" "${USE_KML}")
status_optional_feature("Z+M point coordinate support" "${USE_POINT_Z_M}")
status_optional_feature("XML Mapfile support" "${USE_XMLMAPFILE}")
status_optional_feature("V8 JavaScript" "${USE_V8}")

message(STATUS " * Mapscripts")
status_optional_feature("Python" "${USE_PYTHON_MAPSCRIPT}")
Expand Down
48 changes: 48 additions & 0 deletions cmake/FindV8.cmake
@@ -0,0 +1,48 @@
# - Find V8
#
# V8_INCLUDE - Where to find v8.h
# V8_LIBS - List of libraries when using V8.
# V8_FOUND - True if V8 found.

get_filename_component(module_file_path ${CMAKE_CURRENT_LIST_FILE} PATH)

# Look for the header file.
find_path(V8_INCLUDE NAMES v8.h PATHS $ENV{V8_ROOT}/include /opt/local/include /usr/local/include /usr/include DOC "Path in which the file v8.h is located." )
mark_as_advanced(V8_INCLUDE)

# Look for the library.
# Does this work on UNIX systems? (LINUX)
find_library(V8_LIBS NAMES v8 PATHS /usr/lib $ENV{V8_ROOT}/lib DOC "Path to v8 library." )
mark_as_advanced(V8_LIBS)

# Copy the results to the output variables.
if (V8_INCLUDE AND V8_LIBS)
message(STATUS "Found v8 in ${V8_INCLUDE} ${V8_LIBS}")
set(V8_FOUND 1)
include(CheckCXXSourceCompiles)
set(CMAKE_REQUIRED_LIBRARIES ${V8_LIBS} pthread)
set(CMAKE_REQUIRED_INCLUDES ${V8_INCLUDE})

check_cxx_source_compiles("
#include <v8.h>
int main()
{
v8::Persistent<v8::Context> ctx;
ctx.Dispose(0);
return 0;
}"
V8_DISPOSE_HAS_ISOLATE)
else ()
set(V8_FOUND 0)
endif ()

# Report the results.
if (NOT V8_FOUND)
set(V8_DIR_MESSAGE "V8 was not found. Make sure V8_LIBS and V8_INCLUDE are set.")
if (V8_FIND_REQUIRED)
message(FATAL_ERROR "${V8_DIR_MESSAGE}")
elseif (NOT V8_FIND_QUIETLY)
message(STATUS "${V8_DIR_MESSAGE}")
endif ()
endif ()
11 changes: 8 additions & 3 deletions mapdraw.c
Expand Up @@ -548,7 +548,7 @@ int msLayerIsVisible(mapObj *map, layerObj *layer)
}
return(MS_FALSE);
}

/* now check class scale boundaries (all layers *must* pass these tests) */
if(layer->numclasses > 0) {
for(i=0; i<layer->numclasses; i++) {
Expand Down Expand Up @@ -852,8 +852,13 @@ int msDrawVectorLayer(mapObj *map, layerObj *layer, imageObj *image)
status = msLayerOpen(layer);
if(status != MS_SUCCESS) return MS_FAILURE;

/* build item list */
status = msLayerWhichItems(layer, MS_FALSE, NULL);
/* build item list. STYLEITEM javascript needs the shape attributes */
if (layer->styleitem &&
(strncasecmp(layer->styleitem, "javascript://", 13) == 0)) {
status = msLayerWhichItems(layer, MS_TRUE, NULL);
}
else
status = msLayerWhichItems(layer, MS_FALSE, NULL);

if(status != MS_SUCCESS) {
msLayerClose(layer);
Expand Down
6 changes: 5 additions & 1 deletion maperror.c
Expand Up @@ -83,7 +83,8 @@ static char *ms_errorCodes[MS_NUMERRORCODES] = {"",
"AGG library error.",
"OWS error.",
"OpenGL renderer error.",
"Renderer error."
"Renderer error.",
"V8 engine error."
};
#ifndef USE_THREAD

Expand Down Expand Up @@ -571,6 +572,9 @@ char *msGetVersion()
#ifdef USE_POINT_Z_M
strcat(version, " SUPPORTS=POINT_Z_M");
#endif
#ifdef USE_V8
strcat(version, " SUPPORTS=V8");
#endif
#ifdef USE_JPEG
strcat(version, " INPUT=JPEG");
#endif
Expand Down
5 changes: 3 additions & 2 deletions maperror.h
Expand Up @@ -78,8 +78,9 @@ extern "C" {
#define MS_NULLPARENTERR 38
#define MS_AGGERR 39
#define MS_OWSERR 40
#define MS_OGLERR 42
#define MS_RENDERERERR 43
#define MS_OGLERR 41
#define MS_RENDERERERR 42
#define MS_V8ERR 43
#define MS_NUMERRORCODES 44

#define MESSAGELENGTH 2048
Expand Down
2 changes: 2 additions & 0 deletions mapfile.c
Expand Up @@ -5896,6 +5896,8 @@ int initMap(mapObj *map)

msInitQuery(&(map->query));

map->v8context = NULL;

return(0);
}

Expand Down
102 changes: 70 additions & 32 deletions maplayer.c
Expand Up @@ -649,8 +649,10 @@ int msLayerWhichItems(layerObj *layer, int get_all, char *metadata)

if(layer->classitem) nt++;
if(layer->filteritem) nt++;
if(layer->styleitem && strcasecmp(layer->styleitem, "AUTO") != 0) nt++;

if(layer->styleitem &&
(strcasecmp(layer->styleitem, "AUTO") != 0) &&
(strncasecmp(layer->styleitem, "javascript://", 13) != 0)) nt++;

if(layer->filter.type == MS_EXPRESSION)
nt += msCountChars(layer->filter.string, '[');

Expand Down Expand Up @@ -721,7 +723,9 @@ int msLayerWhichItems(layerObj *layer, int get_all, char *metadata)
/* layer items */
if(layer->classitem) layer->classitemindex = string2list(layer->items, &(layer->numitems), layer->classitem);
if(layer->filteritem) layer->filteritemindex = string2list(layer->items, &(layer->numitems), layer->filteritem);
if(layer->styleitem && strcasecmp(layer->styleitem, "AUTO") != 0) layer->styleitemindex = string2list(layer->items, &(layer->numitems), layer->styleitem);
if(layer->styleitem &&
(strcasecmp(layer->styleitem, "AUTO") != 0) &&
(strncasecmp(layer->styleitem, "javascript://",13) != 0)) layer->styleitemindex = string2list(layer->items, &(layer->numitems), layer->styleitem);
if(layer->labelitem) layer->labelitemindex = string2list(layer->items, &(layer->numitems), layer->labelitem);

/* layer classes */
Expand Down Expand Up @@ -859,41 +863,75 @@ int msLayerGetAutoStyle(mapObj *map, layerObj *layer, classObj *c, shapeObj* sha
*/
int msLayerGetFeatureStyle(mapObj *map, layerObj *layer, classObj *c, shapeObj* shape)
{
char* stylestring;
char* stylestring = NULL;
if (layer->styleitem && layer->styleitemindex >=0) {
stylestring = shape->values[layer->styleitemindex];
/* try to find out the current style format */
if (strncasecmp(stylestring,"style",5) == 0) {
resetClassStyle(c);
c->layer = layer;
if (msMaybeAllocateClassStyle(c, 0))
return(MS_FAILURE);

msUpdateStyleFromString(c->styles[0], stylestring, MS_FALSE);
if(c->styles[0]->symbolname) {
if((c->styles[0]->symbol = msGetSymbolIndex(&(map->symbolset), c->styles[0]->symbolname, MS_TRUE)) == -1) {
msSetError(MS_MISCERR, "Undefined symbol \"%s\" in class of layer %s.", "msLayerGetFeatureStyle()",
c->styles[0]->symbolname, layer->name);
return MS_FAILURE;
}
stylestring = msStrdup(shape->values[layer->styleitemindex]);
}
else if (strncasecmp(layer->styleitem,"javascript://",13) == 0) {
#ifdef USE_V8
char *filename = layer->styleitem+13;

if (!map->v8context) {
msV8CreateContext(map);
if (!map->v8context)
{
msSetError(MS_V8ERR, "Unable to create v8 context.", "msLayerGetFeatureStyle()");
return MS_FAILURE;
}
} else if (strncasecmp(stylestring,"class",5) == 0) {
if (strcasestr(stylestring, " style ") != NULL) {
/* reset style if stylestring contains style definitions */
resetClassStyle(c);
c->layer = layer;
}

if (*filename == '\0') {
msSetError(MS_V8ERR, "Invalid javascript filename: \"%s\".", "msLayerGetFeatureStyle()", layer->styleitem);
return MS_FAILURE;
}

stylestring = msV8GetFeatureStyle(map, filename, layer, shape);
#else
msSetError(MS_V8ERR, "V8 Javascript support is not available.", "msLayerGetFeatureStyle()");
return MS_FAILURE;
#endif
}
else { /* unknown styleitem */
return MS_FAILURE;
}

/* try to find out the current style format */
if (!stylestring)
return MS_FAILURE;

if (strncasecmp(stylestring,"style",5) == 0) {
resetClassStyle(c);
c->layer = layer;
if (msMaybeAllocateClassStyle(c, 0)) {
free(stylestring);
return(MS_FAILURE);
}

msUpdateStyleFromString(c->styles[0], stylestring, MS_FALSE);
if(c->styles[0]->symbolname) {
if((c->styles[0]->symbol = msGetSymbolIndex(&(map->symbolset), c->styles[0]->symbolname, MS_TRUE)) == -1) {
msSetError(MS_MISCERR, "Undefined symbol \"%s\" in class of layer %s.", "msLayerGetFeatureStyle()",
c->styles[0]->symbolname, layer->name);
free(stylestring);
return MS_FAILURE;
}
msUpdateClassFromString(c, stylestring, MS_FALSE);
} else if (strncasecmp(stylestring,"pen",3) == 0 || strncasecmp(stylestring,"brush",5) == 0 ||
strncasecmp(stylestring,"symbol",6) == 0 || strncasecmp(stylestring,"label",5) == 0) {
msOGRUpdateStyleFromString(map, layer, c, stylestring);
} else {
}
} else if (strncasecmp(stylestring,"class",5) == 0) {
if (strcasestr(stylestring, " style ") != NULL) {
/* reset style if stylestring contains style definitions */
resetClassStyle(c);
c->layer = layer;
}

return MS_SUCCESS;
msUpdateClassFromString(c, stylestring, MS_FALSE);
} else if (strncasecmp(stylestring,"pen",3) == 0 || strncasecmp(stylestring,"brush",5) == 0 ||
strncasecmp(stylestring,"symbol",6) == 0 || strncasecmp(stylestring,"label",5) == 0) {
msOGRUpdateStyleFromString(map, layer, c, stylestring);
} else {
resetClassStyle(c);
}
return MS_FAILURE;

free(stylestring);
return MS_SUCCESS;
}


Expand Down
3 changes: 3 additions & 0 deletions mapobject.c
Expand Up @@ -137,6 +137,9 @@ void msFreeMap(mapObj *map)

msFreeQuery(&(map->query));

if (map->v8context)
msV8FreeContext(map);

msFree(map);
}

Expand Down
1 change: 1 addition & 0 deletions mapserver-config.h.in
Expand Up @@ -36,6 +36,7 @@
#cmakedefine USE_SDE 1
#cmakedefine SDE64 1
#cmakedefine USE_EXTENDED_DEBUG 1
#cmakedefine USE_V8 1

/*windows specific hacks*/
#if defined(_WIN32)
Expand Down
19 changes: 18 additions & 1 deletion mapserver.h
Expand Up @@ -134,7 +134,6 @@ typedef ms_uint32 * ms_bitarray;
#include "cgiutil.h"



#include <sys/types.h> /* regular expression support */

/* The regex lib from the system and the regex lib from PHP needs to
Expand Down Expand Up @@ -1825,6 +1824,10 @@ void msPopulateTextSymbolForLabelAndString(textSymbolObj *ts, labelObj *l, char

queryObj query;
#endif

#ifdef USE_V8
void *v8context;
#endif
};

/************************************************************************/
Expand Down Expand Up @@ -2785,6 +2788,20 @@ void msPopulateTextSymbolForLabelAndString(textSymbolObj *ts, labelObj *l, char
/* ==================================================================== */
/* end of prototypes for functions in mapsmoothing.c */
/* ==================================================================== */

/* ==================================================================== */
/* prototypes for functions in mapv8.cpp */
/* ==================================================================== */
#ifdef USE_V8
MS_DLL_EXPORT char* msV8GetFeatureStyle(mapObj *map, const char *filename,
layerObj *layer, shapeObj *shape);
MS_DLL_EXPORT void msV8CreateContext(mapObj *map);
MS_DLL_EXPORT void msV8FreeContext(mapObj *map);
#endif
/* ==================================================================== */
/* end of prototypes for functions in mapv8.cpp */
/* ==================================================================== */

#endif


Expand Down

0 comments on commit a966c1c

Please sign in to comment.