在我的#if USE_X11
// This will make some window managers obey the border being turned on/off.
// Most other modern window managers will allow the border to be placed
// off-screen:
// Unfortunatly stoopid MetaCity raises the window. Sigh
CreatedWindow::find(window)->sendxjunk();
# if 1
// Supposedly this tells the new X window managers to put this atop
// the taskbar. My tests have shown absolutly zero effect, so this is
// either wrong or the window managers are ignoreing it. Newer X
// window managers seem to work without this, they probably recognize
// attempts to make the window the size of the screen
// this method does in fact work, and is used below in my maximize()
// so it should probably work here as well
// possible problem is that sometimes one have to process/flush events
// i.e. by using fltk::wait(1) to have this working
// Perhaps below code can be done correctly(?) again - look at maximize()
// (or perhaps Im totally wrong, Im new to Xlib ;) --Rafal
static Atom _NET_WM_STATE;
static Atom _NET_WM_STATE_REMOVE;
static Atom _NET_WM_STATE_ADD;
static Atom _NET_WM_STATE_FULLSCREEN;
if (!_NET_WM_STATE) {
# define MAX_ATOMS 30
Atom* atom_ptr[MAX_ATOMS];
const char* names[MAX_ATOMS];
int i = 0;
# define atom(a,b) atom_ptr[i] = &a; names[i] = b; i++
atom(_NET_WM_STATE , "_NET_WM_STATE");
atom(_NET_WM_STATE_REMOVE , "_NET_WM_STATE_REMOVE");
atom(_NET_WM_STATE_ADD , "_NET_WM_STATE_ADD");
atom(_NET_WM_STATE_FULLSCREEN, "_NET_WM_STATE_FULLSCREEN");
# undef atom
Atom atoms[MAX_ATOMS];
XInternAtoms(xdisplay, (char**)names, i, 0, atoms);
for (; i--;) *atom_ptr[i] = atoms[i];
}
XEvent e;
memset( &e, 0, sizeof(e) );
e.type = ClientMessage;
e.xclient.window = xid(window);
e.xclient.message_type = _NET_WM_STATE;
e.xclient.format = 32;
e.xclient.data.l[0] = fullscreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
e.xclient.data.l[1] = _NET_WM_STATE_FULLSCREEN;
e.xclient.data.l[2] = 0;
e.xclient.data.l[3] = 0;
e.xclient.data.l[4] = 0;
XSendEvent(xdisplay, RootWindow(xdisplay, xscreen), 0,
SubstructureNotifyMask|SubstructureRedirectMask, &e);
# endif
# endif
内部,我试图在成功添加节点后从空间索引中删除节点。但是节点仍然在索引中,我仍然能够使用空间Cypher查询找到它。
这是我的代码的摘录:
TransactionEventHandler.beforeCommit()
这是Neo4j Spatial中的已知错误吗?无论如何,我怎样才能实现我的目标?
PS:我使用的是Neo4j 2.3.2和Neo4j Spatial 0.15-neo4j-2.3.1。
使用空间将节点添加到空间索引时 它创建一个代理节点并将该节点添加到IndexProvider接口 空间索引,保持原始节点与 图中RTree索引。
我发现,代理节点始终包含“id”属性。它指向原始节点。我们甚至不需要手动添加它(如William所提出的)。使用它我们可以找到代理节点,以便手动删除它。
有时我们的图表可能如下所示:
有时可能会变得有点复杂:
在图片上:
因此,我们可以使用以下Cypher查询来查找和删除代理节点:
Index<Node> index = getGraphDatabaseService().index().forNodes("locations", SpatialIndexProvider.SIMPLE_POINT_CONFIG);
if (node.hasProperty("lat") && node.hasProperty("lon")) {
index.add(node, null, null); // it works perfectly
} else {
index.remove(node); // it doesn't work
}
以下是我目前在MATCH (:ReferenceNode)-[:LAYER]-()-[:RTREE_ROOT]-()-[*..]-(n {id:{id}}) MATCH (n)-[r:RTREE_REFERENCE]-() DELETE r, n
内使用的完整解决方案:
TransactionEventHandler
答案 0 :(得分:1)
使用空间IndexProvider接口将节点添加到空间索引时,它会创建代理节点,并将该节点添加到空间索引中,从而使原始节点保持独立来自图中的RTree索引。
这与空间库的其他接口不一致,并引起了一些混淆。有关详细信息,请参阅this SO post。
您可以向要编制索引的节点添加id属性,以便在要从索引中删除代理节点时找到代理节点,或者使用空间Java API从空间层添加/删除节点以避免创建代理节点。