Spatial4j里的主要的两个类是SpatialContext和JtsSpatialContext,它们持有距 离计算和经纬度转换为图形的相关类。上文说过SpatialContext是通过这么一个流程得到 的:AbstractSpatialFieldType.init()——SpatialContextFactory.makeSpatialContext()àSpatialContextFactory.newSpatialContext()——new SpatialContext(geo,calculator,worldBounds)。在 SpatialContextFactory.makeSpatialContext()方法中会接受solr中schema.xml文件中配置的相应字 段的一些属性键值对作为参数,从参数中实例化特定的SpatialContextFactory(判断到底是使用 SpatialContextFactory还是JtsSpatialContextFactory,区别上文也说过了),除此之外还有初始化 geo.calculator,worldBounds(刚好是构造SpatialContext需要的参数)的值(这三个属性也可通过 schema.xml文件进行显式配置),这三个属性的解释如下: geo表示是否启用地理空间,不显示配置的话 默认为true;calculator表示计算空间距离的具体方法,可以配置为haversine(对应的算法为 GeodesicSphereDistCalc.Haversine),lawOfCosines(对应的算法为 GeodesicSphereDistCals.LawOfCosines),vincentySphere(对应的算法为 GeodesicSphereDistCals.Vincenty),cartesian(对应的算法为 CartesianDistCalc),cartesian2(对应的算法为CartesianDistCalc(true)),不显式配置默认为 GeodesicSphereDistCalc.Haversine;worldBounds表示配置的世界的一个范围(即搜索所在的区域),不显式配置 默认为整个地球(-180,180,-90,90),需要注意的是如果你配置了geo属性为true或者没有指定geo属性的值那么 worldBounds属性值必须为” -180,180,-90,90”,换句话说如果你配置了geo=true或者没有指定geo,worldBounds属性可以不用配置,如果你配置了 geo=false,那么worldBounds可以不用配置如果需要配置则minX必须<=maxX(minX代表-180,maxX代表 180),否则报错。 上面的工作都是为了实例化SpatialContext而做的,实例化之后需要 makeShapeReadWriter,即ShapeReadWriter和JtsShapeReadWriter(该实例通过 JtsSpatialContext的makeShapeReadWrite方法获得),实例化JtsSpatialContext和 SpatialContext的不同之处在于实例化JtsSpatialContext时需要初始化GeometryFactory(jts包的类),有 了ShapeReadWriter和JtsShapeReadWriter之后就可以对经纬度和图形之间进行转化了,它们的主要工作就是这个。 (待续。。。)